It is important to think that if you fill in a space with a +, there must be an expression here to fill-the number so that all the back out. This is very important.
Then found that the answer is only related to the prefix product, line tree maintenance can be.
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#defineMAXN 100500#defineMoD 1000000007using namespacestd;Long Longn,q,table[maxn],a[maxn],x,y;Long Longroot,tot=0,ls[maxn<<2],rs[maxn<<2],sum1[maxn<<2],sum2[maxn<<2];voidget_table () {table[0]=1; for(Long LongI=1; i<=100000; i++) Table[i]= (table[i-1]*3)%MoD;}voidPushup (Long LongNowLong LongLeftLong LongRight ) { Long LongMid= (left+right) >>1; Long LongRet1,ret2,ret3; Ret1= ((Sum1[ls[now]]-sum2[ls[now]]) +MoD); Ret2=Sum2[ls[now]]; Ret3=Sum1[rs[now]]; Sum1[now]= ((Ret1*table[right-mid])%mod+ ((ret2*table[right-mid-1])%mod*2)%mod)%mod+ (ret3*ret2)%mod)%MoD; Sum2[now]= (Sum2[ls[now]]*sum2[rs[now]])%MoD;}voidBuildLong Long&now,Long LongLeftLong LongRight ) { Now=++tot; if(left==Right ) {Sum1[now]=sum2[now]=a[left]%MoD; return; } Long LongMid= (left+right) >>1; Build (Ls[now],left,mid); Build (Rs[now],mid+1, right); Pushup (now,left,right);}voidModifyLong LongNowLong LongLeftLong LongRightLong LongPosLong Longx) { if(left==Right ) {Sum1[now]=sum2[now]=x%MoD; return; } Long LongMid= (left+right) >>1; if(pos<=mid) Modify (LS[NOW],LEFT,MID,POS,X); ElseModify (rs[now],mid+1, right,pos,x); Pushup (now,left,right);}intMain () {scanf ("%lld%lld",&n,&q); for(Long LongI=1; i<=n;i++) scanf ("%lld",&A[i]); Get_table (); Build (Root,1, N); for(Long LongI=1; i<=q;i++) {scanf ("%lld%lld",&x,&y); Modify (Root,1, N,x,y); printf ("%lld\n", sum1[root]%MoD); } return 0;}
Bzoj 4597 Random Sequence