the
Solving
The tree with the MO Team Classic problem.
With the foreshadowing of the front: common with the MO team and ordinary tree Mo team, this problem is not alone.
The answer and the order of the walk is irrelevant, only with each kind of candy to eat several times about, obviously can O (1) Mobile maintenance.
And then there's No. The tree with the MO team can be.
This question is a bit constant problem, on the uoj was stuck for half a day 90 points. Finally, the size of the block has been lowered a little bit.
As if the actual situation with the MO team block size is not necessarily N2/3 N^{2/3} optimal, personal feeling slightly smaller may be better effect.
#include <cstdio> #include <cmath> #include <algorithm> using namespace std;
const int maxn=100005, maxe=200005;
typedef long Long LL;
int N,M,Q,Q1,Q2,C[MAXN],V[MAXN],W[MAXN],B[MAXN],SUM[MAXN];
LL ANS,ANS[MAXN];
int Son[maxe],fir[maxn],nxt[maxe],tot;
int dfn[maxn],tim,g,blk,blg[maxn],stk[maxn],top;
BOOL VIS[MAXN];
int ANC[MAXN][20],DEP[MAXN];
void Dfs (int x,int pre) {anc[x][0]=pre for (int i=1;i<=17;i++) anc[x][i]=anc[anc[x][i-1]][i-1]; Dfn[x]=++tim;
int bottom=top;
for (int j=fir[x];j;j=nxt[j]) if (son[j]!=pre) {dep[son[j]]=dep[x]+1; Dfs (SON[J],X);
if (top-bottom>=blk) {g++;
while (Top!=bottom) blg[stk[top--]]=g;
}} stk[++top]=x;
} struct data{int x,y,id,tim;} Q[MAXN];
struct op{int x,c[2];} OP[MAXN]; BOOL MY_CMP (const data &a,const data &b) {if (blg[a.x]==blg[b.x)) {if (Blg[a.y]==blg[b.y]) return a.tim& Lt
B.tim;
Return blg[a.y]<blg[b.y]; Return blg[a.x]<Blg[b.x]; } inline void Add (int x,int y) {son[++tot]=y; nxt[tot]=fir[x]; fir[x]=tot;} int LCA (int x,int y) {if (dep[x]<de
P[y]) swap (x,y);
for (int j=17;j>=0;j--) if (Dep[anc[x][j]]>=dep[y]) x=anc[x][j];
if (x==y) return x;
for (int j=17;j>=0;j--) if (Anc[x][j]!=anc[y][j]) x=anc[x][j], y=anc[y][j];
return anc[x][0];
inline int getint () {char ch=getchar (); int res=0,ff=1; while (!) ('
0 ' <=ch&&ch<= ' 9 ')) {if (ch== '-') ff=-1; Ch=getchar ();}
while (' 0 ' <=ch&&ch<= ' 9 ') res= (res<<3) + (res<<1) +ch-' 0 ', Ch=getchar ();
return RES*FF; } inline void Updata (int x,int k) {if (k==1) ans+= ((LL) w[++sum[x]) *v[x]; else ans-= ((LL) w[sum[x]--]) *v[x]; inline
void rev (int x) {if (vis[x]) updata (c[x],-1); else Updata (c[x],1);
Vis[x]^=1;
} inline void Change (int u,int v,int id,int k) {if (vis[op[id].x)) Updata (c[op[id].x],-1), Updata (op[id].c[k],1);
C[OP[ID].X]=OP[ID].C[K]; } inline void work (int x,int y) {WHile (x!=y) {if (dep[x]<dep[y)) swap (x,y); Rev (x);
X=ANC[X][0];
int main () {freopen ("bzoj3052.in", "R", stdin);
Freopen ("Bzoj3052.out", "w", stdout);
scanf ("%d%d%d", &n,&m,&q);
for (int i=1;i<=m;i++) v[i]=getint ();
for (int i=1;i<=n;i++) w[i]=getint ();
for (int i=1;i<=n-1;i++) {int x=getint (), Y=getint (); Add (x,y);
Add (y,x);
for (int i=1;i<=n;i++) c[i]=b[i]=getint ();
for (int i=1;i<=q;i++) {int pd=getint ();
if (PD) {q1++; Q[q1].x=getint (), Q[q1].y=getint (); q[q1].id=q1; q[q1].tim=q2;
if (Dfn[q[q1].x]>dfn[q[q1].y]) swap (Q[Q1].X,Q[Q1].Y);
else{q2++ op[q2].x=getint (); Op[q2].c[1]=getint (); Op[q2].c[0]=b[op[q2].x];
B[OP[Q2].X]=OP[Q2].C[1]; } blk=pow (n,0.54);
DFS (1,1);
Sort (q+1,q+1+q1,my_cmp); Q[0].x=q[0].y=1;
q[0].tim=0; for (int i=1,now=0;i<=q1;i++) {while (Now<q[i].tim) ChaNge (q[i-1].x,q[i-1].y,++now,1);
while (Q[i].tim<now) change (q[i-1].x,q[i-1].y,now--, 0); Work (q[i-1].x,q[i].x);
Work (Q[I-1].Y,Q[I].Y);
int _lca=lca (Q[I].X,Q[I].Y); Rev (_LCA); Ans[q[i].id]=ans;
Rev (_LCA);
for (int i=1;i<=q1;i++) printf ("%lld\n", Ans[i]);
return 0; }