After offline with religion as the first keyword, the operation time for the second keyword sorting.
< Alpha > block tree, Offline AC, online tle ...
#include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <queue >using namespace Std;queue<int>q;int f,c;inline void R (int &x) {c=0;f=1; for (;c< ' 0 ' | | C> ' 9 '; C=getchar ()) if (c== '-') f=-1; for (x=0;c>= ' 0 ' &&c<= ' 9 '; C=getchar ()) (x*=10) + = (c ' 0 '); X*=f;} void P (int x) {if (x<10) putchar (x+ ' 0 '); Else{p (X/10);p Utchar (x%10+ ' 0 ');}} #define N 100001int en,first[n],next[n<<1],v[n<<1];void addedge (const int &u,const int &v) {V[++en] =v;next[en]=first[u];first[u]=en;} int Tops[n],en4;bool delta[n];struct thing{int op,type,x,y,t,p;} Th[n*3];bool operator < (const THING &a,const THING &b) {return a.type!=b.type? a.type<b.type:a.t<b.t;} int N,m,w[n],ty[n],en2,en3;int fa[n],dep[n],siz[n],top[n],sz,maxv[n],sumv[n];int anss[N];void makeblock () {Q.push (1 ); while (!q.empty ()) {int U=q.front (); Q.pop (); for (int i=first[u];i;i=next[i]) if (V[i]!=fa[u]) {Dep[v[i]]=dep[u]+1; Fa[v[i]]=u; if (Siz[top[u]]<sz) {++siz[top[u]]; Top[v[i]]=top[u]; } q.push (V[i]); }}}void dfs (int u,int sumnow,int maxnow) {maxv[u]=maxnow; Sumv[u]=sumnow; for (int i=first[u];i;i=next[i]) if (V[i]!=fa[u]&&top[v[i]]==top[u]) DFS (V[i],sumnow+w[v[i]],max (Maxnow, W[v[i]));} void Dfs0 (int U) {maxv[u]=sumv[u]=w[u]=0;for (int i=first[u];i;i=next[i]) if (V[i]!=fa[u]&&top[v[i]]==top[u]) Dfs0 (V[i]);} void update (const int &P,CONST int &val) {if (!delta[top[p]]) {DFS0 (top[p]); Delta[top[p]]=1; } w[p]=val;if (P==top[p]) DFS (p,val,val); Else Dfs (P,val+sumv[fa[p]],max (val,maxv[fa[p]));} int Query_max (int u,int V) {int res=0; while (U!=V) {if (Top[u]==top[v]) {if (Dep[u]<dep[v]) swap (U,V); Res=max (res,delta[top[u]]?w[u]:0); U=fa[u]; } else {if (dep[TOP[U]]<DEP[TOP[V]) swap (U,V); Res=max (res,delta[top[u]]?maxv[u]:0); U=fa[top[u]]; }} return Max (res,delta[top[u]]?w[u]:0);} int query_sum (int u,int V) {int res=0; while (U!=V) {if (Top[u]==top[v]) {if (Dep[u]<dep[v]) swap (U,V); res+= (delta[top[u]]?w[u]:0); U=fa[u]; } else {if (Dep[top[u]]<dep[top[v]]) swap (U,V); res+= (delta[top[u]]?sumv[u]:0); U=fa[top[u]]; }} return res+ (delta[top[u]]?w[u]:0);} int main () {int A, b; Char op[3]; R (n); R (M); for (int i=1;i<=n;++i) {R (W[i]); R (Ty[i]); Th[i].type=ty[i]; Th[i].x=i; th[i].t=i; Th[i].y=w[i]; }for (int i=1;i<n;++i) {R (A); R (B); Addedge (A, b); Addedge (B,a); } sz=sqrt (0.03* (double) n); for (int i=1;i<=n;i++) {top[i]=i; Siz[i]=1; } makeblock (); en2=n;for (int i=1;i<=m;++i) {Op[0]=getchar (); Op[1]=getchar (); R (A);R (B); if (op[0]== ' C ' &&op[1]== ' C ') {Th[++en2].type=ty[a]; Th[en2].x=a; th[en2].y=0; Th[en2].t=en2; Ty[a]=b; Th[++en2].type=ty[a]; Th[en2].x=a; Th[en2].y=w[a]; Th[en2].t=en2; } else if (op[0]== ' C ' &&op[1]== ' W ') {w[a]=b; Th[++en2].type=ty[a]; Th[en2].x=a; Th[en2].y=w[a]; Th[en2].t=en2; } else if (op[0]== ' Q ' &&op[1]== ' S ') {th[++en2].op=1; Th[en2].type=ty[a]; Th[en2].x=a; Th[en2].y=b; Th[en2].t=en2; Th[en2].p=++en3; } else {th[++en2].op=2; Th[en2].type=ty[a]; Th[en2].x=a; Th[en2].y=b; Th[en2].t=en2; Th[en2].p=++en3; }}sort (th+1,th+en2+1); memset (W,0,sizeof (w)); for (int i=1;i<=n;i++) if (top[i]==i) tops[++en4]=i;for (int i=1;i< =en4;++i) delta[tops[i]]=1;for (int i=1;i<=en2;++i) {if (th[i].type!=th[i-1].type&&i!=1) for (int j=1;j< =EN4;++J) delta[tops[j]]=0; if (!th[i].op) update (TH[I].X,TH[I].Y); else if (th[i].op==1) anss[th[i].p]=query_sum(TH[I].X,TH[I].Y); else Anss[th[i].p]=query_max (TH[I].X,TH[I].Y); }for (int i=1;i<=en3;++i) P (Anss[i]), puts (""); return 0;}
< two > tree chain + segment tree
#include <cstdio> #include <algorithm>using namespace std; #define Lson Rt<<1,l,m#define Rson rt< <1|1,m+1,rint f,c;inline void R (int &x) {c=0;f=1; for (;c< ' 0 ' | | C> ' 9 '; C=getchar ()) if (c== '-') f=-1; for (x=0;c>= ' 0 ' &&c<= ' 9 '; C=getchar ()) (x*=10) + = (c ' 0 '); X*=f;} void P (int x) {if (x<10) putchar (x+ ' 0 '); Else{p (X/10);p Utchar (x%10+ ' 0 ');}} #define N 100001int en,first[n],next[n<<1],v[n<<1];void addedge (const int &u,const int &v) {V[++en] =v;next[en]=first[u];first[u]=en;} struct Thing{int op,type,x,y,t,p;} Th[n*3];bool operator < (const THING &a,const THING &b) {return a.type!=b.type? a.type<b.type:a.t<b.t;} int N,m,w[n],ty[n],en2,en3;int anss[n];int dep[n],siz[n],fa[n],son[n],top[n],num[n],tot;void dfs (int U,int d) {Dep[U] =d; Siz[u]=1; for (int i=first[u];i;i=next[i]) if (V[i]!=fa[u]) {fa[v[i]]=u; DFS (V[I],D+1); Siz[u]+=siz[v[i]]; if (siz[v[i]]>siz[Son[u]]) Son[u]=v[i]; }}void dfs2 (int U) {if (Son[u]) {top[son[u]]=top[u]; Num[son[u]]=++tot; DFS2 (Son[u]); } for (int i=first[u];i;i=next[i]) if (V[i]!=fa[u]&&v[i]!=son[u]) {top[v[i]]=v[i]; Num[v[i]]=++tot; DFS2 (V[i]); }}int maxv[n<<2],sumv[n<<2];bool delta[n<<2];void pushdown (const int &rt) {if (Delta[rt]) {Delta [rt<<1]=delta[rt<<1|1]=1; maxv[rt<<1]=maxv[rt<<1|1]=sumv[rt<<1]=sumv[rt<<1|1]=0; delta[rt]=0; }}void Update (int p,int v,int rt,int l,int R) {if (l==r) {maxv[rt]=sumv[rt]=v; Return }pushdown (RT); int m= (l+r>>1); if (p<=m) update (P,v,lson); else update (P,v,rson); sumv[rt]=sumv[rt<<1]+ Sumv[rt<<1|1];maxv[rt]=max (maxv[rt<<1],maxv[rt<<1|1]);} int query1 (int ql,int qr,int rt,int l,int R) {if (QL<=L&&R<=QR) return SUMV[RT];p Ushdown (RT); int m= (l+r> >1), Res=0;if (ql<=m) Res+=query1 (Ql,qr,lson); if (M<QR) res+=query1 (Ql,qr,rson); return res;} int query2 (int ql,int qr,int rt,int l,int R) {if (QL<=L&&R<=QR) return MAXV[RT];p Ushdown (RT); int m= (l+r> >1), Res=0;if (ql<=m) Res=max (Res,query2 (Ql,qr,lson)), if (M<QR) Res=max (Res,query2 (Ql,qr,rson)); return res;} int Query1 (int u,int V) {int F1=top[u],f2=top[v],res=0;while (F1!=F2) {if (Dep[f1]<dep[f2]) { Swap (U,V); Swap (F1,F2); } res+=query1 (Num[f1],num[u],1,1,n); U=FA[F1]; F1=top[u]; } if (Dep[u]>dep[v]) swap (U,V); Return Res+query1 (num[u],num[v],1,1,n);} int Query2 (int u,int V) {int F1=top[u],f2=top[v],res=0;while (F1!=F2) {if (Dep[f1]<dep[f2]) { Swap (U,V); Swap (F1,F2); } Res=max (Res,query2 (num[f1],num[u],1,1,n)); U=FA[F1]; F1=top[u]; } if (Dep[u]>dep[v]) swap (U,V); Return Max (Res,query2 (Num[u],num[v],1,1,n));}int main () {int A, b; Char op[3]; R (n); R (M); for (int i=1;i<=n;++i) {R (W[i]); R (Ty[i]); Th[i].type=ty[i]; Th[i].x=i; th[i].t=i; Th[i].y=w[i]; }for (int i=1;i<n;++i) {R (A); R (B); Addedge (A, b); Addedge (B,a); }top[1]=1; Num[1]=++tot; DFS (a); DFS2 (1); en2=n;for (int i=1;i<=m;++i) {Op[0]=getchar (); Op[1]=getchar (); R (A); R (B); if (op[0]== ' C ' &&op[1]== ' C ') {Th[++en2].type=ty[a]; Th[en2].x=a; th[en2].y=0; Th[en2].t=en2; Ty[a]=b; Th[++en2].type=ty[a]; Th[en2].x=a; Th[en2].y=w[a]; Th[en2].t=en2; } else if (op[0]== ' C ' &&op[1]== ' W ') {w[a]=b; Th[++en2].type=ty[a]; Th[en2].x=a; Th[en2].y=w[a]; Th[en2].t=en2; } else if (op[0]== ' Q ' &&op[1]== ' S ') {th[++en2].op=1; Th[en2].type=ty[a]; Th[en2].x=a; Th[en2].y=b; Th[en2].t=en2; Th[en2].p=++en3; } else {th[++en2].op=2; Th[en2].type=ty[a]; Th[en2].x=a; Th[en2].y=b; Th[en2].t=en2; Th[en2].p=++en3; }}soRT (th+1,th+en2+1); for (int i=1;i<=en2;++i) {if (th[i].type!=th[i-1].type&&i!=1) delta[1]=1; if (!th[i].op) update (NUM[TH[I].X],TH[I].Y,1,1,N); else if (th[i].op==1) anss[th[i].p]=query1 (TH[I].X,TH[I].Y); else Anss[th[i].p]=query2 (TH[I].X,TH[I].Y); }for (int i=1;i<=en3;++i) P (Anss[i]), puts (""); return 0;}
Block tree tree chain split segment Tree bzoj3531 [Sdoi2014] Travel