CF1286D-LCC【动态dp,数学期望】
生活随笔
收集整理的這篇文章主要介紹了
CF1286D-LCC【动态dp,数学期望】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/CF1286D
題目大意
nnn個粒子,第iii個在xix_ixi?,速度是viv_ivi?,有pi100\frac{p_i}{100}100pi??的概率朝左飛,有1?pi1001-\frac{p_i}{100}1?100pi??的概率往右飛,求期望第一對粒子碰撞的時間(如果永遠沒有碰撞則為000)
1≤n≤1051\leq n\leq 10^51≤n≤105
解題思路
期望+最小值顯然是不能直接搞的,我們可以考慮枚舉最小值,因為第一次碰撞的一定是相鄰的粒子,所以這樣的情況最多只有2n2n2n種。
然后對于一個值作為最小值的時候有些情況是不被允許的,設fi,0/1f_{i,0/1}fi,0/1?表示在被允許情況且iii向左/右的概率,此時每個轉移可以寫成一個2×22\times 22×2的矩陣,從大到小枚舉最小值就可以每次只修改一個矩陣了,動態dpdpdp維護即可。
時間復雜度:O(23nlog?n)O(2^3n\log n)O(23nlogn)
code
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=1e5+10,M=2e6+10,S=2,P=998244353; struct Matrix{ll a[S][S]; }c,f[N],w[N<<2]; struct node{ll op,w,x;double cw; }d[N<<1]; ll ans,n,cnt,inv[M],x[N],v[N],p[N]; Matrix operator*(const Matrix &a,const Matrix &b){memset(c.a,0,sizeof(c.a));for(ll i=0;i<S;i++)for(ll j=0;j<S;j++)for(ll k=0;k<S;k++)(c.a[i][j]+=a.a[i][k]*b.a[k][j]%P)%=P;return c; } void Change(ll x,ll L,ll R,ll pos,const Matrix &val){if(L==R){w[x]=val;return;}ll mid=(L+R)>>1;if(pos<=mid)Change(x*2,L,mid,pos,val);else Change(x*2+1,mid+1,R,pos,val);w[x]=w[x*2]*w[x*2+1];return; } bool cmp(node x,node y) {return x.cw>y.cw;} signed main() {inv[1]=1;for(ll i=2;i<=2e6;i++)inv[i]=P-inv[P%i]*(P/i)%P;scanf("%lld",&n);for(ll i=1;i<=n;i++)scanf("%lld%lld%lld",&x[i],&v[i],&p[i]),p[i]=p[i]*inv[100]%P;for(ll i=1;i<n;i++)d[++cnt]=(node){0,(x[i+1]-x[i])*inv[v[i]+v[i+1]]%P,i+1,(double)(x[i+1]-x[i])/((double)(v[i]+v[i+1]))};f[1].a[0][1]=p[1];f[1].a[0][0]=P+1-p[1];Change(1,1,n,1,f[1]);for(ll i=1;i<n;i++){f[i+1].a[0][1]=p[i+1];if(v[i]>v[i+1])d[++cnt]=(node){1,(x[i+1]-x[i])*inv[v[i]-v[i+1]]%P,i+1,(double)(x[i+1]-x[i])/((double)(v[i]-v[i+1]))};else f[i+1].a[1][1]=p[i+1];if(v[i]<v[i+1])d[++cnt]=(node){-1,(x[i+1]-x[i])*inv[v[i+1]-v[i]]%P,i+1,(double)(x[i+1]-x[i])/((double)(v[i+1]-v[i]))};else f[i+1].a[0][0]=P+1-p[i+1];Change(1,1,n,i+1,f[i+1]);}sort(d+1,d+1+cnt,cmp);ll last=(w[1].a[0][0]+w[1].a[0][1])%P;for(ll i=1;i<=cnt;i++){ll x=d[i].x;if(d[i].op==0)f[x].a[1][0]=P+1-p[x];else if(d[i].op==1)f[x].a[1][1]=p[x];else f[x].a[0][0]=P+1-p[x];Change(1,1,n,x,f[x]);(ans+=(w[1].a[0][0]+w[1].a[0][1]-last+P)%P*d[i].w%P)%=P;last=(w[1].a[0][0]+w[1].a[0][1])%P;}printf("%lld\n",ans);return 0; }總結
以上是生活随笔為你收集整理的CF1286D-LCC【动态dp,数学期望】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dct是什么意思 英文全称是什么
- 下一篇: 吉林市有什么好玩的地方 吉林市景点介绍