Left-leaning tree
bzoj4003 Fortress Conquest
The main topic: a tree, each point has a defensive value. M samurai, has the attack and the starting position, attacks a point will attack to the father, the attack power is equal to a point of the defensive force can attack, or die. The samurai attacks each point and the attack is changed, plus or multiplied by a number (the number of times guaranteed to be non-negative). Ask the number of knights killed in each city and the points each samurai has to attack.
Idea: Using left-leaning tree to maintain a point of samurai information, the weight of the changes in the form of *a+b update.
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#defineN 300005#defineLL Long Longusing namespacestd;structuse{intl,r,d; LL Ad,ch;} Hp[n];structuu{intAI; LL Vi,hi;} Ci[n];intrt[n]={0},point[n]={0},next[n],cur[n],zh[n],zt,pa[n],ca[n]={0},dis[n]={0}; LL Vi[n];voidPushdown (intx) { intL,r;l=hp[x].l;r=HP[X].R; if(l) {Vi[l]=vi[l]*hp[x].ch+Hp[x].ad; Hp[l].ad=hp[l].ad*hp[x].ch+Hp[x].ad; hp[l].ch=hp[l].ch*hp[x].ch; }if(R) {Vi[r]=vi[r]*hp[x].ch+Hp[x].ad; Hp[r].ad=hp[r].ad*hp[x].ch+Hp[x].ad; hp[r].ch=hp[r].ch*hp[x].ch; }hp[x].ad=0ll;hp[x].ch=1LL;}intMergeintXinty) { if(!x)returny; if(!y)returnx; Pushdown (x);p ushdown (y); if(vi[x]>Vi[y]) swap (x, y); HP[X].R=merge (Hp[x].r,y); if(hp[hp[x].l].d<hp[hp[x].r].d) Swap (HP[X].L,HP[X].R); if(!HP[X].R) hp[x].d=0; ElseHp[x].d=hp[hp[x].r].d+1; returnx;}voidWorkintu) { while(rt[u]&&vi[rt[u]]<Ci[u].hi) { ++Ca[u];p ushdown (Rt[u]); Pa[rt[u]]=dis[pa[rt[u]]]-Dis[u]; Rt[u]=merge (HP[RT[U]].L,HP[RT[U]].R); }if(u!=1){ if(Rt[u]) {if(ci[u].ai==0) {Vi[rt[u]]+=CI[U].VI; Hp[rt[u]].ad+=CI[U].VI; }Else{Vi[rt[u]]*=CI[U].VI; Hp[rt[u]].ad*=CI[U].VI; hp[rt[u]].ch*=CI[U].VI; } } }Else while(Rt[u]) {pushdown (rt[u]); Pa[rt[u]]=dis[pa[rt[u]]]-dis[u]+1; Rt[u]=merge (HP[RT[U]].L,HP[RT[U]].R); }}intMain () {intn,m,i,fi,u,v; scanf ("%d%d",&n,&m); for(i=1; i<=n;++i) scanf ("%i64d",&Ci[i].hi); for(i=2; i<=n;++i) {scanf ("%d%d%i64d",&fi,&ci[i].ai,&CI[I].VI); Next[i]=point[fi];cur[fi]=point[fi]=i; } for(i=1; i<=m;++i) {scanf ("%i64d%d",&vi[i],&FI); Pa[i]=fi; Hp[i]= (use) {0,0,0, 0LL,1LL}; RT[FI]=merge (Rt[fi],i); }zh[zt=1]=1;d is[1]=1; while(ZT) {u=ZH[ZT]; if((V=cur[u]) >0) {Dis[v]=dis[u]+1; zh[++zt]=v; Cur[u]=Next[v]; }Else{ --ZT; for(v=point[u];v;v=Next[v]) Rt[u]=merge (Rt[u],rt[v]); Work (u); } } for(i=1; i<=n;++i) printf ("%d\n", Ca[i]); for(i=1; i<=m;++i) printf ("%d\n", Pa[i]);}
View Code
Can and Heap