[概率DP][多项式取模] NOI2017.day1 T3 泳池
来源:互联网 发布:webclient post json 编辑:程序博客网 时间:2024/04/30 18:00
lzz写了题解,但是我没看懂…
就自己想了个DP
f(i,j)表示高度为i,长度为j的局域,i这个行存在障碍,前i-1行不存在障碍,能选取的区域<=k的概率
那么
其中p为一个格子安全的概率,q,为一个格子危险的概率。
那么
这样转移一下就可以了
可以按段转移,设
那么
这是一个线性递推式,用多项式取模可以完成。
#include <cstdio>#include <iostream>#include <algorithm>#include <string>#include <cstring>using namespace std;const int N=5100,P=998244353;inline int Pow(int x,int y){ int ret=1; for(;y;y>>=1,x=1LL*x*x%P) if(y&1) ret=1LL*ret*x%P; return ret;}inline int inv(int x){ return Pow(x,P-2);}inline void add(int &x,int y){ (x+=y)%=P;}int n,k,x,y,p,q;int f[N][N],g[N],pw[N],h[N],a[N],F[N],d[N];int rev[N],w[2][N],num;inline void NTT(int *a,int n,int r){ for(int i=1;i<n;i++) if(rev[i]>i) swap(a[i],a[rev[i]]); for(int i=1;i<n;i<<=1) for(int j=0;j<n;j+=i<<1) for(int k=0;k<i;k++){ int x=a[j+k],y=1LL*w[r][n/(i<<1)*k]*a[i+j+k]%P; a[j+k]=(x+y)%P; a[i+j+k]=(x+P-y)%P; } if(!r) for(int i=0,iv=Pow(n,P-2);i<n;i++) a[i]=1LL*a[i]*iv%P;}inline void Pre(int n,int l){ for(int i=1;i<n;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<l); int g=Pow(3,(P-1)/n),ig=inv(g); w[0][0]=w[1][0]=1; for(int i=1;i<n;i++) w[0][i]=1LL*w[0][i-1]*ig%P,w[1][i]=1LL*w[1][i-1]*g%P;}inline void Mul(int *a,int *b,int m){ int l=-1,M; for(M=1;M<(m<<1);M<<=1) l++; Pre(M,l); if(a==b){ NTT(a,M,1); for(int i=0;i<M;i++) a[i]=1LL*a[i]*a[i]%P; NTT(a,M,0); return ; } NTT(a,M,1); NTT(b,M,1); for(int i=0;i<M;i++) a[i]=1LL*a[i]*b[i]%P; NTT(a,M,0); NTT(b,M,0);}int tmp[N],A[N],B[N];void Inv(int *a,int *b,int n){ if(n==1) return b[0]=inv(a[0]),void(); Inv(a,b,n+1>>1); static int tmp[N]; int L=0; while(!(n>>L&1)) L++; Pre(n<<1,L); for(int i=0;i<n;i++) tmp[i]=a[i]; for(int i=n;i<n<<1;i++) tmp[i]=0; NTT(tmp,n<<1,1); NTT(b,n<<1,1); for(int i=0;i<n<<1;i++) tmp[i]=(2LL*b[i]%P+P-1LL*tmp[i]*b[i]%P*b[i]%P)%P; NTT(tmp,n<<1,0); for(int i=0;i<n;i++) b[i]=tmp[i]; for(int i=n;i<n<<1;i++) b[i]=0;}int t[N],bb[N];inline void Div(int *a,int n,int *b,int m){ static int tmp[N],A[N],B[N]; for(int i=0;i<m;i++) t[i]=b[m-i-1]; for(int i=0;i<n;i++) A[i]=a[n-i-1]; int nn=1,d=n-m+1; for(;nn<d<<1;nn<<=1); for(int i=n;i<nn;i++) A[i]=0; for(int i=d;i<nn;i++) t[i]=0; for(int i=0;i<nn;i++) B[i]=0; Inv(t,B,nn); for(int i=d;i<nn;i++) B[i]=0; Mul(A,B,max(n,d)); for(int i=d;i<=n<<1;i++) A[i]=0; for(int i=0;i<d;i++) if(i>d-i-1) swap(A[i],A[d-i-1]); for(int i=0;i<m;i++) t[i]=b[i]; Mul(t,A,max(d,m)); for(int i=0;i<n;i++) a[i]=(a[i]+P-t[i])%P;}inline void mul(int *a,int *b,int m){ Mul(a,b,m); Div(a,2*m,d,m+1);}inline void Pow(int *a,int m,int n,int *b){ for(;n;n>>=1,mul(a,a,m)) if(n&1) mul(b,a,m);}inline int solve(int m){ memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); f[m+1][1]=1LL*pw[m]*q%P; g[0]=1; g[1]=f[m+1][1]; for(int i=m;i;i--){ f[i][0]=1; for(int j=1;(i-1)*j<=m && j<=m;j++) for(int s=1;s<=j;s++){ if(s>1) add(f[i][j],1LL*f[i][s-1]*g[j-s]%P*pw[i-1]%P*q%P); add(f[i][j],1LL*g[s-1]*g[j-s]%P*pw[i-1]%P*q%P); } if(i==1) memcpy(h,g,sizeof(h)); for(int j=1;(i-1)*j<=m && j<=m;j++) add(g[j],f[i][j]); } if(n<=m) return g[n]; for(int i=m+1;i;i--) h[i]=1LL*h[i-1]*q%P; m++; memset(a,0,sizeof(a)); memset(d,0,sizeof(d)); memset(F,0,sizeof(F)); for(int i=0;i<m;i++) d[i]=(P-h[m-i])%P; d[m]=1; a[1]=1; F[0]=1; Pow(a,m,n,F); int ret=0; for(int i=0;i<m;i++) add(ret,1LL*F[i]*g[i]%P); return ret;}int main(){ scanf("%d%d%d%d",&n,&k,&x,&y); p=1LL*x*inv(y)%P; q=(1+P-p)%P; pw[0]=1; for(int i=1;i<=k;i++) pw[i]=1LL*pw[i-1]*p%P; printf("%d\n",(solve(k)+P-solve(k-1))%P); return 0;}
阅读全文
1 0
- [概率DP][多项式取模] NOI2017.day1 T3 泳池
- 【BZOJ4944】【NOI2017】泳池 概率DP 常系数线性递推 特征多项式 多项式取模
- 【NOI2017模拟.4.1】 Dice【概率,期望,DP,精度优化】
- noip2016 Day1 T3:换教室 (期望值+floyd+dp)
- Noip2014 Day1 T3 飞扬的小鸟(Dp)
- Noip2015 Day1 T3 斗地主(Dfs+Dp优化)
- Noip2016 Day1 T3 换教室(Floyd + Dp)
- 【NOIP2016提高组T3】换教室-Floyd+概率DP
- GDKOI2016 Day1 T3 寻宝
- NOIP2013 DAY1 T3
- 集训Day1 T3 整除
- Noip 提高组 2016 Day1 T3 换教室 Floyd+期望dp
- NOIP2013 Day1 T3 货车运输
- 济南学习 Day1 T3 am
- 济南学习 Day1 T3 pm
- NOIP2013 Day1 T3 货车运输
- NOIP2017 Day1 T3 逛公园
- noip2017 Day1 T3 逛公园
- Android不同的图片模式,每个像素占用的字节大小
- org.apache.hadoop.hbase.PleaseHoldException: Master is initializing 的一种原因
- Ansible--通过SSH与远程服务器连接
- 一种不常见的跨域方式--使用CSS3特性做跨域
- ubuntu软件安装
- [概率DP][多项式取模] NOI2017.day1 T3 泳池
- oracle里对某个用户下的对象数量的统计
- ZooKeeper启动占用8080端口
- Unity Apex寻路插件 与Mecanim动画结合。
- springboot logback日志
- Android_自定义View、Fragment
- 【Java笔记】单例模式设计模式
- [LeetCode] 3Sum 三数之和 Python
- LBP特征识别