Test Instructions: links
Method: Mo team on the tree
parsing:
First consider a team of algorithms, tree tiles
and how to do it.
you can set two pointers, and then move the pointer in a certain sort of way so that the complexity can be over.
observed that the problem is 100s, n^2 is GG, but slightly smaller than n^2 is not GG,
so the role of sequencing is reflected.
according to the block of the left endpoint is the first keyword, the right end of the block is the second keyword occurrence time for the Third keyword sort.
There is a total of N of 1/3 square blocks, so all the queries of the left and right end of the block is the most value of the next N of 2/3 of the species, for each, the modification of the time will change from the tail to the head, so multiply by a q,n,q the same order, so the total complexity O (N^5/3), If the two endpoints of the two queries are within the same block, the complexity is transferred within the block, and the size of each block is N^2/3 times, so the complexity is also O (N^5/3). Not forced to O (n^2).
and then modify it?
it would be better to bind a violent change.
count the number of queries before each change. Each time the enumeration is asked, the violence modifies the modification operation.
of course to sort, so it seems more linear 2333
and then the team went to the tree.
don't read the wrong question.
Code:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <
Algorithm> #define N 100100 using namespace std;
typedef long Long LL;
int n,m,q,cnt;
int head[n];
ll V[n],w[n];
int c[n];
int sta[n];
int belong[n];
int deep[n];
int fa[n][21];
int s[n];
int v[n];
ll Print[n];
int status[n];
int sqr23n;
int Tot,top,cntque,cntcha; struct node {int from,to,next;}
edge[n<<1]; struct query {int l,r,blockl,blockr,appcha,lca,no,alltime;}
Que[n]; struct change {int pt,pre,sub,no,alltime;}
Cha[n];
void Init () {memset (head,-1,sizeof (head));
Cnt=1;
} void Edgeadd (int from,int to) {edge[cnt].to=to;
Edge[cnt].next=head[from];
head[from]=cnt++;
} void Dfs (int now,int depth,int Fafa) {v[now]=1,fa[now][0]=fafa,deep[now]=depth;
int bot=top;
for (int i=head[now];i!=-1;i=edge[i].next) {int to=edge[i].to;
if (V[to]) continue;
DFS (To,depth+1,now);
if (top-bot>=sqr23n) {tot++;
do {belong[sta[top--]]=tot;
}while (Top!=bot);
}} Sta[++top]=now;
} int LCA (int x,int y) {if (Deep[x]<deep[y]) swap (x, y);
for (int i=20;i>=0;i--) {if (deep[fa[x][i]]>=deep[y]&&fa[x][i]!=0) x=fa[x][i];
} for (int i=20;i>=0;i--) {if (fa[x][i]!=fa[y][i]&&fa[x][i]!=0&&fa[y][i]!=0)
X=fa[x][i],y=fa[y][i];
} if (x==y) return x;
return fa[x][0];
} ll ans;
void Upd (int x) {if (status[x]) {status[x]=0;
ANS-=W[S[C[X]]]*V[C[X]];
s[c[x]]--;
}else {status[x]=1;
s[c[x]]++;
ANS+=W[S[C[X]]]*V[C[X]];
}} void Update (int u,int V,int LCA) {while (U!=LCA) {UPD (U);
U=FA[U][0];
} while (V!=LCA) {Upd (v);
V=FA[V][0]; }} int cmp (query A,query b) {if (A.blockl==b.blockl) {if (a.blocKr==b.blockr) {return a.appcha<b.appcha;
}else return a.blockr<b.blockr;
}else return a.blockl<b.blockl;
} void trans (int chaid,int opt) {int flag=0;
if (opt) flag=1,swap (cha[chaid].pre,cha[chaid].sub);
C[cha[chaid].pt]=cha[chaid].sub;
if (status[cha[chaid].pt]) {Ans-=v[cha[chaid].pre]*w[s[cha[chaid].pre]];
s[cha[chaid].pre]--;
s[cha[chaid].sub]++;
Ans+=v[cha[chaid].sub]*w[s[cha[chaid].sub]];
} if (flag) swap (cha[chaid].pre,cha[chaid].sub);
} int main () {init ();
scanf ("%d%d%d", &n,&m,&q);
Sqr23n=pow (n,2.0/3.0);
for (int i=1;i<=m;i++) scanf ("%lld", &v[i]);
for (int i=1;i<=n;i++) scanf ("%lld", &w[i]);
for (int i=1;i<n;i++) {int x, y;
scanf ("%d%d", &x,&y);
Edgeadd (x, y), Edgeadd (y,x);
} dfs (1,1,0);
while (top>0) {belong[sta[top--]]=tot;
} for (int i=1;i<=20;i++) { for (int j=1;j<=n;j++) {fa[j][i]=fa[fa[j][i-1]][i-1];
}} for (int i=1;i<=n;i++) scanf ("%d", &c[i]);
for (int i=1;i<=q;i++) {int jd,x,y;
scanf ("%d%d%d", &jd,&x,&y);
if (JD) {if (Belong[x]>belong[y]) swap (x, y);
Que[++cntque].l=x,que[cntque].r=y;
Que[cntque].blockl=belong[x],que[cntque].blockr=belong[y];
Que[cntque].appcha=cntcha;
Que[cntque].lca=lca (QUE[CNTQUE].L,QUE[CNTQUE].R);
Que[cntque].no=cntque;
Que[cntque].alltime=cntque;
}else {Cha[++cntcha].pt=x,cha[cntcha].pre=c[x],cha[cntcha].sub=c[x]=y,cha[cntcha].no=cntcha;
Cha[cntcha].alltime=cntque;
}} sort (que+1,que+cntque+1,cmp);
int Cnntcha=cntcha;
Update (QUE[1].L,QUE[1].R,QUE[1].LCA);
UPD (QUE[1].LCA); while (cnntcha>0) {if (cha[cnntcha].alltime<que[1].alltime) break;
Trans (cnntcha,1);
cnntcha--;
} while (Cnntcha<cntcha) {if (cha[cnntcha+1].alltime>=que[1].alltime) break;
Trans (cnntcha+1,0);
cnntcha++;
} Print[que[1].no]=ans;
UPD (QUE[1].LCA);
int TL=QUE[1].L,TR=QUE[1].R;
for (int i=2;i<=cntque;i++) {int Tmp=lca (QUE[I].L,TL);
Update (TL,QUE[I].L,TMP);
Tmp=lca (QUE[I].R,TR);
Update (TR,QUE[I].R,TMP);
UPD (QUE[I].LCA);
while (cnntcha>0) {if (cha[cnntcha].alltime<que[i].alltime) break;
Trans (cnntcha,1);
cnntcha--;
} while (Cnntcha<cntcha) {if (cha[cnntcha+1].alltime>=que[i].alltime) break;
Trans (cnntcha+1,0);
cnntcha++;
} Print[que[i].no]=ans;
UPD (QUE[I].LCA);
TL=QUE[I].L,TR=QUE[I].R;
} for (int i=1;i<=cntque;i++) printf ("%lld\n", Print[i]); }