1 条题解
-
0
正解应该不是高斯消元,但是高消可以过喵喵喵。
首先这是一个随机游走问题,所以我们建方程组,设 为点 期望到达终点的时间(因为进入终点之后不会再走了),设 为可走方向数。
$$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}$$令 否则翻转。则现在我们得到的是一个 band-matrix 矩阵,即对角线及其前后 位置非 的矩阵。
对于这种有效位置较少的矩阵,高斯消元的复杂度为 , 为元素个数。我们每次找主元的时候最多只需要向下 行必然能找到(否则这一位为自由元)。而当前元向右最多影响 个,向下最多影响 个方程,回带的时候也是向上带 个即可。
关于空间问题,每行由对角线向前开 个,向后开 个即可,记录偏移量,
vector存储。最后答案就是 。
消元部分代码如下:
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
- 上传者