[probability DP] CF494C Helping People

Keywords: pip

[title]
CF
There is a sequence aaa with nnn length and mmm operations. Each operation has the probability of PIP ﹣ IPI ﹣ [l i, ri] [l ﹣ I, R ﹣ I] [Li, ri ﹣ plus one. The intervals of all operations are only completely inclusive and disjoint. Find the expectation of the maximum value in aaa after all operations.
n≤105,m≤5000n\leq 10^5,m\leq 5000n≤105,m≤5000

[solutions]
The restriction given by the title is actually a tree structure, with the outer layer of the completely contained interval being the father and the inner layer being the son.

It is observed that the number of operands is relatively small, that is to say, the last added weight is relatively small. Consider DP\text{DP}DP for this thing.

Let fi, JF {I, j} fi, j} denote the probability that the maximum value of the interval represented by point iii is ≤ mxi+j \ Leq MX ﹐ I + j ≤ mxi+j after the completion of the operation of subtree iii, where mxix ﹐ imxi ﹐ denotes the maximum value of the original interval. If the current operation is not executed, only the probability sum of the maximum value in all subtrees ≤ MX I + j \ Leq mx_i + j ≤ mxi+j is needed. Otherwise, we need the probability sum of the maximum value of all subtrees ≤ MX I + j − 1\leq mx_i+j-1 ≤ mxi+j − 1, then we can get:

fi,j=pi∏fv,mxi+j−1−mxv+(1−pi)∏fv,mxi+j−mxvf_{i,j}=p_i\prod f_{v,mx_i+j-1-mx_v}+(1-p_i)\prod f_{v,mx_i+j-mx_v}fi,j​=pi​∏fv,mxi​+j−1−mxv​​+(1−pi​)∏fv,mxi​+j−mxv​​

Complexity O (n log ⁡ n + m2) O (n \ log n + m ^ 2) O(nlog + m2)
[reference code]

#include<bits/stdc++.h>
#define pb push_back
using namespace std;

typedef double db;
const int N=1e5+10,M=5010;
int n,m,Log[N],fc[20],st[18][N];
db f[M][M];
vector<int>G[M];

struct data
{
	int l,r,mx;db p;
	data(int _l=0,int _r=0,int _m=0,db _p=0):l(_l),r(_r),mx(_m),p(_p){}
}q[M];
bool cmp(const data&A,const data&B){return A.l==B.l?A.r>B.r:A.l<B.l;}

void dfs(int x)
{
	db p=1;
	for(auto v:G[x]) dfs(v);
	for(auto v:G[x]) p*=f[v][q[x].mx-q[v].mx];
	f[x][0]=(1-q[x].p)*p;
	for(int i=1;i<=m;++i)
	{
		db p1=1,p2=1;
		for(auto v:G[x]) p1*=f[v][min(q[x].mx+i-q[v].mx-1,m)],p2*=f[v][min(q[x].mx+i-q[v].mx,m)];
		f[x][i]=q[x].p*p1+(1-q[x].p)*p2;
	}
}

int query(int l,int r)
{
	int k=Log[r-l+1];
	return max(st[k][l],st[k][r-fc[k]+1]);
}

int main()
{
#ifdef Durant_Lee
	freopen("CF494C.in","r",stdin);
	freopen("CF494C.out","w",stdout);
#endif
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i) scanf("%d",&st[0][i]);
	fc[0]=1;for(int i=1;i<20;++i) fc[i]=fc[i-1]<<1;
	for(int i=2;i<=n;++i) Log[i]=Log[i>>1]+1;
	for(int j=1;j<17;++j) for(int i=1;i+fc[j]-1<=n;++i)
		st[j][i]=max(st[j-1][i],st[j-1][i+fc[j-1]]);
	for(int i=1;i<=m;++i)
	{
		scanf("%d%d%lf",&q[i].l,&q[i].r,&q[i].p);
		q[i].mx=query(q[i].l,q[i].r);
	}
	q[++m]=data(1,n,query(1,n),0);
	sort(q+1,q+m+1,cmp);
	for(int i=2;i<=m;++i) for(int j=i-1;j;--j) 
		if(q[j].l<=q[i].l && q[i].r<=q[j].r) {G[j].pb(i);break;}
	dfs(1);db ans=f[1][0]*q[1].mx;
	for(int i=1;i<=m;++i) ans+=(f[1][i]-f[1][i-1])*(q[1].mx+i);
	printf("%lf\n",ans);
	return 0;
}

Posted by nEmoGrinder on Sun, 24 Nov 2019 12:30:39 -0800