Description
Input
Output
Sample Input
Sample Input Sample Output 84
131
27
HINT
The total time limit on Bzoj is 250S. Exam Time Single Point 10S
This question can be done with Mo team. First, the DFS sequence is obtained. Then change the query on the tree to the interval in the DFS sequence. And then it's the same as the team in the queue.
Sort the first, second, and third keywords with the left end, right end, and time respectively
As for the size of the block I think it's not too outrageous, OK. Look on the Internet are n^ (2/3). But I wrote it myself. n^ (1/2) faster
Handed a few times reluctantly stuck into the 100S
#include <queue> #include <cmath> #include <cstdio> #include <string> #include <cstring> #
Include<iostream> #include <algorithm> using namespace std;
struct line {int s,t;
int next;
}A[200001];
int head[100001];
int edge;
inline void Add (int s,int t) {A[edge].next=head[s];
Head[s]=edge;
A[edge].s=s;
a[edge].t=t;
} struct que {int u,v,t;
int p;
Long long X;
}ASK[100001]; struct Rechange {int x,s,t;}
C[100001];
--------------------------LCA int deep[100001];
int fa[100001];
BOOL v[100001];
int ans[100001][22];
Long Long val[100001],w[100001];
inline void BFs (int r) {int i,j;
Deep[r]=1;
for (i=0;i<=21;i++) ans[r][i]=r;
Queue <int>Q; while (!
Q.empty ()) Q.pop ();
Q.push (R);
V[r]=true; while (!
Q.empty ()) {int D=q.front ();
Q.pop ();
for (i=head[d];i!=0;i=a[i].next) {int t=a[i].t; if (!v[t]) {v[t]=true;
Q.push (t);
Fa[t]=d;
deep[t]=deep[d]+1;
Ans[t][0]=d;
int DT;
Long long DC;
for (j=1;j<=21;j++) {dt=ans[t][j-1];
ANS[T][J]=ANS[DT][J-1]; }}}}} inline int swim (int x,int y) {while (Deep[x]!=deep[y]) {int I
= 0;
while (Deep[ans[y][i]]>deep[x]) i++;
if (i!=0) i--;
Y=ans[y][i];
} return y;
} Inline Long long LCA (int x,int y) {if (Deep[x]>deep[y]) {int t=x;
X=y;
y=t;
} y=swim (x, y);
int i=21;
while (x!=y) {while (ans[x][i]==ans[y][i]&&i>0) i--;
X=ans[x][i]; Y=ans[y][i];
} return x;
}//-------------------------LCA int col[200001],col1[200001];
int tot;
int dline[300001];
int ld[200001],rd[200001];
int pos[200001];
inline bool Cmp1 (que x,que y) {if (pos[x.u]==pos[y.u]) {if (X.V<Y.V) return true;
else if (x.v==y.v&&x.t<y.t) return true;
return false;
} if (Pos[x.u]<pos[y.u]) return true;
return false;
} inline bool Cmp2 (que x,que y) {if (X.P<Y.P) return true;
return false;
} inline void dfsx (int d) {int i,j;
for (i=head[d];i!=0;i=a[i].next) {int t=a[i].t;
if (!v[t]) {v[t]=true;
tot++;
dline[tot]=t;
Ld[t]=tot;
DFSX (t);
tot++;
dline[tot]=t;
Rd[t]=tot;
}}} long long sum,sa[100001];
inline void reverse (int x) {if (!v[x]) {V[x]=true;
sa[col[x]]++;
SUM+=W[SA[COL[X]]]*VAL[COL[X]];
} else {v[x]=false;
SUM-=W[SA[COL[X]]]*VAL[COL[X]];
sa[col[x]]--;
}} inline void Decchange (int x) {if (v[c[x].x]) {sum-=w[sa[c[x].t]]*val[c[x].t];
sa[c[x].t]--;
sa[c[x].s]++;
SUM+=W[SA[C[X].S]]*VAL[C[X].S];
} Col[c[x].x]=c[x].s;
} inline void Incchange (int x) {if (v[c[x].x]) {SUM-=W[SA[C[X].S]]*VAL[C[X].S];
sa[c[x].s]--;
sa[c[x].t]++;
SUM+=W[SA[C[X].T]]*VAL[C[X].T];
} col[c[x].x]=c[x].t;
} int main () {//Freopen ("Park.in", "R", stdin);//Freopen ("Park.out", "w", stdout);
int n,q,m;
scanf ("%d%d%d", &n,&q,&m);
int i;
int s,t;
for (i=1;i<=q;i++) scanf ("%lld", &val[i]);
for (i=1;i<=n;i++) scanf ("%lld", &w[i]);
for (i=1;i<=n-1;i++) {scanf ("%d%d", &s,&t);
edge++; Add (s,t);
edge++;
Add (t,s);
} for (i=1;i<=n;i++) {scanf ("%d", &col[i]);
Col1[i]=col[i];
} BFS (1);
memset (v,false,sizeof (v));
V[1]=true;
tot++;
Dline[1]=1;
Ld[1]=1;
DFSX (1);
tot++;
Dline[tot]=1;
Rd[1]=tot;
Double xtx=1.8/3.0;
int Nt=int (sqrt (tot));
for (i=1;i<=tot;i++) pos[i]= (i-1)/nt+1;
int x;
int p1=0,p2=0;
for (i=1;i<=m;i++) {scanf ("%d", &x);
if (x==0) {p2++;
scanf ("%d%d", &c[p2].x,&c[p2].t);
C[p2].s=col1[c[p2].x];
col1[c[p2].x]=c[p2].t;
} else {p1++;
scanf ("%d%d", &ASK[P1].U,&ASK[P1].V);
if (LD[ASK[P1].U]>LD[ASK[P1].V]) swap (ASK[P1].U,ASK[P1].V);
ASK[P1].U=RD[ASK[P1].U];
ASK[P1].V=LD[ASK[P1].V]; IF (ASK[P1].U>=ASK[P1].V) ask[p1].u=ld[dline[ask[p1].u]];
ASK[P1].P=P1;
ASK[P1].T=P2;
}} sort (ASK+1,ASK+1+P1,CMP1);
memset (v,false,sizeof (v));
int l=ask[i].u,r=ask[i].u-1;
int time=0;
for (i=1;i<=p1;i++) {while (l<ask[i].u) {reverse (dline[l]);
l++;
} while (l>ask[i].u) {l--;
Reverse (dline[l]);
} while (R<ASK[I].V) {r++;
Reverse (dline[r]);
} while (R>ASK[I].V) {reverse (dline[r]);
r--;
} while (time>ask[i].t) {decchange (time);
time--;
} while (time<ask[i].t) {time++;
Incchange (time);
} T=LCA (Dline[l],dline[r]);
int flag=false; if (DLINE[ASK[I].U]!=T&&DLINE[ASK[I].V]!=t) {reverse (T);
Flag=true;
} ask[i].x=sum;
if (flag) reverse (t);
} sort (ASK+1,ASK+1+P1,CMP2);
for (i=1;i<=p1;i++) printf ("%lld\n", ask[i].x);
return 0; }