CF 282 C Helping people
"The original question " is not affixed.
" nonsense " has not written a blog for a long time. (I'm not going to tell you that I wrote it offline) so came the water experience.
" Source Brief " CF 282 C
" Summary of the original question " There are N (10^5) individuals, each with initial money. The M (5000) operation L,r,p is given. Each time l~r these people have a chance P (0<=p<=1) give them a dollar each. The expectation of the maximum value of the last owner's money.
The " algorithm brief " first establishes the tree structure of these operations (can draw on the segment tree). The node I represents the range Li~ri, its father must contain it, it contains also all its subtrees. For convenience, create a l=1,r=n,p=0 invalid node as the root.
observed that the range of M is small, we use f[i][j] to indicate in the range of node I, plus the amount of money <=j Expectations (note that the original amount can be calculated with RMQ). As for why it is <=, because the prefix is used and--anyway, the F-count prefix and a bit. So to node I, we open an array of tmp[j] to indicate that the maximum (note or prefix and nature) of the shadow in all subtrees is added to the expectation of J element.
Then Tmp[j]=∏f[son][mx[i]+j-mx[son]];
Mx[o] is the maximum amount of the original interval o.
(The prefix and nature of F are used here.)
Notice that after the completion of a step tmp[j]-=tmp[j-1], the cancellation of the prefix and nature.
Then our task is to find out all f values of I.
Then ans[i][j]=ans[i][j-1]+tmp[j-1]*p[i]+tmp[j]* (1-p[i]);
ANS[I][J-1]: prefix and
Tmp[j-1]*p[i]: Maximum plus j-1 in a child tree, and currently
tmp[j]* (1-p[i]): The largest plus J in a child tree, and currently does not add
After all the f[i][j], we are satisfied with the new Dot K, the last ans
Ans=ans[m][0]*mx[m]+σ (Ans[m][i]-ans[m][i-1]) * (mx[m]+i);
The "* essence " is similar to the tree-shaped algorithm of divide and conquer.
Code
#include <cstdio> #include <algorithm> #include <cmath> #define N 100005#define M 5005using namespace Std;struct arr{int l,r;double p;} A[m];int f[n][18],mx[n],used[n],n,i,j,t,m,k;double ans[m][m],tmp[m],ans;inline int ask (int x,int y) {int len= (int) log2 (y-x+1); Return Max (f[x][len],f[y-(1<<len) +1][len]);} inline int cmp (const arr &a,const arr &b) {return A.R-A.L<B.R-B.L;} int main () {scanf ("%d%d", &n,&m); for (i=1;i<=n;i++) scanf ("%d", &f[i][0]); for (j=1;j<=17;j++) for (i=1;i<=n;i++) t=i+ (1<< (j-1)), F[i][j]=max (F[i][j-1], (t<=n)? f[t][j-1]:0); for (i=1;i<=m;i++) scanf ("%d%d%lf", &A[I].L,&A[I].R,&A[I].P); A[++m]= (arr) {1,n,0}; Sort (a+1,a+m+1,cmp); for (i=1;i<=m;i++) {mx[i]=ask (A[I].L,A[I].R); for (k=0;k<=m;k++) tmp[k]=1.0; for (j=1;j<i;j++) if (A[j].l>=a[i].l&&a[j].r<=a[i].r&&!used[j]) {used[j]=1; for (k=0;k<=m;k++) if (mx[i]+K-MX[J]<=M) Tmp[k]*=ans[j][mx[i]+k-mx[j]; } for (k=m;k;k--) tmp[k]-=tmp[k-1]; ans[i][0]= (1-A[I].P) *tmp[0]; for (k=1;k<=m;k++) ans[i][k]=ans[i][k-1]+tmp[k-1]*a[i].p+tmp[k]* (1-A[I].P); ANS[I][K-1]: Plus k-1 expectations (Ans[i] is the prefix and nature)//tmp[k-1]*p[i]: The largest k-1 in the child tree, and currently add//tmp[k]* (1-p[i]): The child tree is the largest plus k, and currently does not add} an S=ANS[M][0]*MX[M]; for (i=1;i<=m;i++) ans+= (Ans[m][i]-ans[m][i-1]) * (mx[m]+i); printf ("%.10LF", ANS);}
Codeforces #282 Div 1 C Helping people