Topic: Given a tree, each point has a color, provides two kinds of operation:
1. Ask the σv[a[i]]*w[k on the path between two points], where a[i] represents the color of this point, K indicates that the dot is the K-th occurrence of this color
2. Change the color of a point
The vfleaking of the http://vfleaking.blog.163.com/blog/static/174807634201311011201627/
With modified MO team on the tree ... If you don't bring any changes, you'll be fine.
If modified, the size of the block is n^ (2/3)
When the query is sorted, the first key value is the left end of the block, the second key is the right end of the block, the third key value is the query time
Then change the point on the chain by jumping to the next one, then process the changes
This ultimately ensures that the worst-case complexity is O (n^ (5/3)) without forcing O (n^2) ...
Remember that tle is not necessarily a constant or a dead loop. It's probably the Mo team who wrote it. Recommended tle check it out.
Also recommended in the middle of the night to brush this problem ... Otherwise it is easy to cause the people excrement ...
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include < Algorithm> #define M 100100using namespace std;namespace istream{const int l=1<<15; Char Buffer[l]; Char *s,*t; inline char Get_char () {if (s==t) {t= (S=buffer) +fread (Buffer,1,l,stdin); if (s==t) return EOF; } return *s++; } inline int get_int () {int re=0; char c; Do C=get_char (); while (c< ' 0 ' | | C> ' 9 '); while (c>= ' 0 ' &&c<= ' 9 ') re= (re<<3) + (re<<1) + (c ' 0 '), C=get_char (); return re; }} struct abcd{int to,next;} table[m<<1];struct query{int x,y,pos; BOOL operator < (const query &y) const;} queries[m];struct modification{int X,from,to,pos;} Modifications[m];int head[m],tot;int n,m,q,b,end;bool flag;int a[m],value[m],incuriosity[m];int Fa[M][20],belong[M] , Size[m],dpt[m],pos[m];int Cnt[m];bool V[m];long Long Now,ans[m];bool query:: operator < (const query &y) const{if (flag) {if (belong[x]!=belong[y.x]) Return belong[x]<belong[y.x]; if (Belong[y]!=belong[y.y]) return belong[y]<belong[y.y]; return POS < Y.pos; } else {if (belong[x]!=belong[y.x]) return belong[x]<belong[y.x]; return::p Os[y] <::p OS[Y.Y]; }}void Add (int x,int y) {table[++tot].to=y; TABLE[TOT].NEXT=HEAD[X]; Head[x]=tot;} void DFS (int x) {int i; static int cnt=0,t=0; if (!fa[x][0]| | size[belong[fa[x][0]]]==b) size[belong[x]=++cnt]++; else size[Belong[x]=belong[fa[x][0]]]++; Dpt[x]=dpt[fa[x][0]]+1;pos[x]=++t; for (I=head[x];i;i=table[i].next) if (table[i].to!=fa[x][0]) Fa[table[i].to][0]=x,dfs (table[i].to);} int LCA (int x,int y) {int J; if (Dpt[x]<dpt[y]) swap (x, y); for (j=17;j>=0;j--) if (Dpt[fa[x][j]]>=dpt[y]) x=fa[x][j]; if (x==y) return x; for (j=17;j>=0;j--) if (Fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j]; return fa[x][0];} void change (int x) {v[x]^=1; if (v[x]==1) {cnt[a[x]]++; if (cnt[a[x]]>=1) now+= (Long Long) value[a[x]]*incuriosity[cnt[a[x]]; } else {if (cnt[a[x]]>=1) now-= (Long Long) value[a[x]]*incuriosity[cnt[a[x]]; cnt[a[x]]--; }}void Change (modification Temp,bool flag) {if (flag) swap (temp.from,temp.to); a[temp.x]=temp.to; if (v[temp.x]) {if (cnt[temp.from]>=1) now-= (Long Long) Value[temp.from]*incuriosity[cnt[temp.from]] ; cnt[temp.from]--; cnt[temp.to]++; if (cnt[temp.to]>=1) now+= (Long Long) value[temp.to]*incuriosity[cnt[temp.to]]; }}int Main () {int i,j,x,y,p,temp,lca; cin>>n>>m>>q; for (i=1;i<=m;i++) value[i]=istream::get_int (); for (i=1;i<=n;i++) incuriosity[i]=istream::get_inT (); for (i=1;i<n;i++) {x=istream::get_int (); Y=istream::get_int (); ADD (x, y); ADD (Y,X); } for (i=1;i<=n;i++) a[i]=istream::get_int (); Temp=0; for (i=1;i<=q;i++) {p=istream::get_int (); X=istream::get_int (); Y=istream::get_int (); if (p==1) {if (Pos[x]>pos[y]) swap (x, y); Queries[++temp].pos=temp; Queries[temp].x=x; Queries[temp].y=y; } else {flag=1; Modifications[++end].x=x; MODIFICATIONS[END].FROM=A[X]; Modifications[end].to=a[x]=y; Modifications[end].pos=temp; }} q=temp; if (flag) b=static_cast<int> (POW (n,2.0/3.0) +1e-7); else b=static_cast<int> (sqrt (n) +1e-7); DFS (1); for (j=1;j<=17;j++) for (i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1]; X=y=1;temp=end; Sort (queries+1,queries+q+1); for (i=1;i<=q;i++) {Lca=lca (x,queries[i].x); for (j=x;j!=lca;j=fa[j][0]) Change (j); for (j=queries[i].x;j!=lca;j=fa[j][0]) Change (j); Lca=lca (Y,QUERIES[I].Y); for (j=y;j!=lca;j=fa[j][0]) Change (j); for (j=queries[i].y;j!=lca;j=fa[j][0]) Change (j); Lca=lca (X=QUERIES[I].X,Y=QUERIES[I].Y); Change (LCA); for (; temp>0 && modifications[temp].pos>=queries[i].pos; temp--) Change (modifications[temp],1); for (; temp<end && modifications[temp+1].pos<queries[i].pos;temp++) Change (modifications[tem p+1],0); Ans[queries[i].pos]=now; Change (LCA); } for (i=1;i<=q;i++) {#ifdef Online_judge printf ("%lld\n", Ans[i]); #endif #ifdef C_POPOQQQ printf ("%i64d\n", Ans[i]); #endif}}
Bzoj 3052 WC2013 Candy Park with modified tree on MO Team