1 条题解

  • 0
    @ 2026-5-11 2:22:41

    正解应该不是高斯消元,但是高消可以过喵喵喵。

    首先这是一个随机游走问题,所以我们建方程组,设 f(i)f(i) 为点 ii 期望到达终点的时间(因为进入终点之后不会再走了),设 PP 为可走方向数。

    $$f(i)=\begin{Bmatrix} 0 & i=ed \\ \frac{f(i-m)+p_{i-m}}{P}+\frac{f(i+m)+p_{i}}{P}+\frac{f(i-1)+q_{i-1}}{P}+\frac{f(i+1)+q_{i}}{P} & else \end{Bmatrix}$$

    mnm\le n 否则翻转。则现在我们得到的是一个 band-matrix 矩阵,即对角线及其前后 DD 位置非 00 的矩阵。

    对于这种有效位置较少的矩阵,高斯消元的复杂度为 O(nD2)\mathcal{O}(nD^2)nn 为元素个数。我们每次找主元的时候最多只需要向下 DD 行必然能找到(否则这一位为自由元)。而当前元向右最多影响 2D2D 个,向下最多影响 DD 个方程,回带的时候也是向上带 DD 个即可。

    关于空间问题,每行由对角线向前开 DD 个,向后开 3D3D 个即可,记录偏移量,vector 存储。

    最后答案就是 f(st)f(st)

    消元部分代码如下:

    typedef long double ld;
    const ld eps=1e-9;
    const int N=2e4+5;
    bool check0(const ld &x){return (x>=-eps&&x<=eps);}
    struct Row{int de;vector<ld>vc;ld rs;}a[N];
    #define a(i,j) a[i].vc[j-a[i].de]
    namespace Gauss{
    	int n,D;
    	void init(int nn,int DD){
    		n=nn,D=DD;
    		for(int i=1;i<=n;i++){
    			a[i].rs=0;
    			a[i].de=i-DD,a[i].vc=vector<ld>(D*4);
    			for(int j=0;j<D*4;j++)a[i].vc[j]=0;
    		}
    	}
    	bool gauss(){
    		for(int x=1;x<=n;x++){
    			int fr=0;
    			for(int i=x;i<=min(n,x+D);i++)
    				if(!check0(a(i,x))){fr=i;break;}
    			if(!fr)return 0;
    			swap(a[fr],a[x]);
    			for(int y=x+1;y<=min(n,x+D);y++){
    				ld c=a(y,x)/a(x,x);
    				if(check0(c))continue;
    				for(int i=x;i<=min(n,a[x].de+(D<<1));i++)
    					a(y,i)-=a(x,i)*c;
    				a[y].rs-=a[x].rs*c;
    			}
    		}
    		for(int x=n;x>=1;x--){
    			a[x].rs/=a(x,x),a(x,x)=1;
    			for(int y=x-1;y>=max(1,x-D);y--){
    				ld c=a(y,x)/a(x,x);
    				if(check0(c))continue;
    				a(y,x)=0,a[y].rs-=a[x].rs*c;
    			}
    		}
    		return 1;
    	}
    }
    
    • 1

    信息

    ID
    5268
    时间
    10000ms
    内存
    1024MiB
    难度
    10
    标签
    递交数
    3
    已通过
    0
    上传者