luogu P3600 隨機數生成器【dp】
阿新 • • 發佈:2019-05-08
() -i 怎麽 break pri 意義 || 選中 main
把期望改成方案數最後除一下,設h[i]為最大值恰好是i的方案數,那麽要求的就是Σh[i]*i
首先包含其他區間的區間是沒有意義的,用單調棧去掉
然後恰好不好求,就改成h[i]表示最大值最大是i的方案數,求Σ(h[i]-h[i-1])*i即可
然後考慮h怎麽求,\( h[i]=\sum_{j=1}^{n}i^j*(m-1)^{n-j}*選j個點使得每個區間都有一個選中點 \)
設選j個點使得每個區間都有一個選中點為g[j],設f[i][j]為前i個必選i點一共選j個點的方案數,那麽\( g[j]=\sum_{fr[i]==q}f[i][j] \)
然後考慮f怎麽求,設fl[i]fr[i]分別是包含i的最左/右區間(如果沒被包含就是左邊第一個和右邊第一個),\( f[i][j]=\sum_{fr[k]+1>=fl[i]} f[k][j-1] \),前綴和優化即可
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int N=2005,mod=666623333; int n,m,q,fl[N],fr[N],f[N][N],s[N][N],g[N],h[N],top,ans; struct qwe { int l,r; }a[N],b[N]; bool cmp(const qwe &a,const qwe &b) { return a.l<b.l||(a.l==b.l&&a.r<b.r); } int read() { int r=0,f=1; char p=getchar(); while(p>'9'||p<'0') { if(p=='-') f=-1; p=getchar(); } while(p>='0'&&p<='9') { r=r*10+p-48; p=getchar(); } return r*f; } int ksm(int a,int b) { int r=1; while(b) { if(b&1) r=1ll*r*a%mod; a=1ll*a*a%mod; b>>=1; } return r; } int main() { n=read(),m=read(),q=read(); for(int i=1;i<=q;i++) a[i].l=read(),a[i].r=read(); sort(a+1,a+1+q,cmp); for(int i=1;i<=q;i++) if(i==1||a[i].l!=a[i-1].l) { while(top&&b[top].r>=a[i].r) top--; b[++top]=a[i];//cerr<<i<<endl; } q=top; // for(int i=1;i<=q;i++) // cerr<<b[i].l<<" "<<b[i].r<<endl; for(int i=1;i<=n;i++) { for(int j=1;j<=q;j++) if(b[j].r>=i) { fl[i]=j; break; } for(int j=q;j>=1;j--) if(b[j].l<=i) { fr[i]=j; break; } if(!fl[i]) fl[i]=fr[i]+1; // cerr<<fl[i]<<" "<<fr[i]<<endl; } f[0][0]=s[0][0]=1; top=0; for(int i=1;i<=n;i++) { s[i][0]=s[i-1][0]; for(int j=1;j<=i;j++) { while(top<i-1&&fr[top]+1<fl[i]) top++; f[i][j]=(s[i-1][j-1]-(top?s[top-1][j-1]:0)+mod)%mod; s[i][j]=(s[i-1][j]+f[i][j])%mod; } } for(int j=1;j<=n;j++) for(int i=1;i<=n;i++) if(fr[i]==q) g[j]=(g[j]+f[i][j])%mod; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) h[i]=(h[i]+1ll*g[j]*ksm(i,j)%mod*ksm(m-i,n-j)%mod)%mod; // cerr<<h[i]<<endl; ans=(ans+1ll*(h[i]-h[i-1]+mod)*i%mod)%mod; } printf("%lld\n",1ll*ans*ksm(ksm(m,n),mod-2)%mod); return 0; }
luogu P3600 隨機數生成器【dp】