[bzoj] 3052: [wc2013]糖果公园 发表于 Mar 26 2015 | 分类于 bzoj | 题意 大家直接看题目好了 传送门 分析莫队算法 代码原谅我用快读卡过去>_< 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189#include <cstdio>#define Rep(i,l,r) for(i=(l);i<=(r);i++)#define Rev(i,r,l) for(i=(r);i>=(l);i--)int CH , NEG ;char chin[10000000],chout[5000000],*pi=chin,*po=chout;template <typename TP>void read(TP &ret){trueret=0;truewhile(*pi<48) pi++;truewhile(*pi>47) ret=ret*10+*pi++-48;}template <typename TP>void print(TP x){truestatic int tim=0;truestatic char p[30];truewhile(x) p[++tim]=x%10+'0',x/=10;truewhile(tim) *po++=p[tim--];true*po++='\n';}typedef long long ll ;#include <algorithm>#include <cmath>#define maxn 100010LL#define maxm 100010LL#define maxq 100010LL#define maxk 18LL//struct FST { int to , next ; } e[maxm<<1] ;int next[maxm<<1] , to[maxm<<1] ;int star[maxn] = {0} , tote = 1 ;void AddEdge(int u , int v) { ++tote ; to[tote] = v ; next[tote] = star[u] ; star[u] = tote ; }int n , m , timnow ;ll ansnow ;int cntblc , szblc , idx , top ;int col[maxn] , cnt[maxn] = {0} , last[maxn] ;int dfn[maxn] , sta[maxn] , belong[maxn] , dep[maxn] , size[maxn] , par[maxn][maxk] ;ll ans[maxq] ;bool vis[maxn] = {0} ;struct QUERY {trueint u , v , lca , id , tim ;truebool operator < (const QUERY& b) const {truetrueif (belong[u]!=belong[b.u]) return belong[u]<belong[b.u] ;truetrueif (belong[v] != belong[b.v]) return belong[v]<belong[b.v] ;truetruereturn id < b.id ;true}} q[maxq] ;struct CHANGE {trueint pos , from , to ;} c[maxq] ;inline void dfs(int u , int fa) {int v , p ;truesta[++top] = u ;truepar[u][0] = fa ;truedfn[u] = ++idx ;truedep[u] = dep[fa]+1 ;truesize[u] = 0 ;truefor (p = star[u] ; p ; p = next[p])truetrueif (v=to[p] , v!=fa) {truetruetruedfs(v , u) ;truetruetruesize[u] += size[v] ;truetruetrueif (size[u] >= szblc) {truetruetruetruesize[u] = 0 ;truetruetruetruecntblc ++ ;truetruetruetruewhile (sta[top] != u) belong[sta[top--]] = cntblc ;truetruetrue}truetrue}truesize[u] ++ ;}inline void ST() {int i , k ;trueRep (k,1,maxk-1)truetrueRep (i,1,n)truetruetruepar[i][k] = par[par[i][k-1]][k-1] ;}inline int LCA(int u , int v) {trueint k ;trueif (dep[u] < dep[v]) std::swap(u,v) ;trueRev (k,maxk-1,0)truetrueif (dep[par[u][k]] >= dep[v]) u = par[u][k] ;trueif (u == v) return u ;trueRev (k,maxk-1,0)truetrueif (par[u][k] != par[v][k])truetruetrueu = par[u][k] , v = par[v][k] ;truereturn par[u][0] ;}ll v[maxn] , w[maxm] ;inline void Reverse(int u) {trueif (vis[u]) { vis[u]=false;ansnow-=v[col[u]]*w[cnt[col[u]]--]; }trueelse { vis[u]=true;ansnow+=v[col[u]]*w[++cnt[col[u]]]; }}inline void Modify(int u , int c) {trueif (vis[u]) {truetrueReverse(u) ;truetruecol[u] = c ;truetrueReverse(u) ;true} else col[u] = c ;}inline void MoveTo(int u,int v) {truewhile (u != v)truetrueif (dep[u] > dep[v]) Reverse(u) , u = par[u][0] ;truetrueelse Reverse(v) , v = par[v][0] ;}inline void GetAns(int i) {trueReverse(q[i].lca) ;trueans[q[i].id] = ansnow ;trueReverse(q[i].lca) ;}#include <ctime>int main() {int i , a , b , Q , cmd ;true#define READtrue#ifdef READtruetruefreopen("park.in" ,"r",stdin ) ;truetruefreopen("park.out","w",stdout) ;true#endiftruefread(pi,1,10000000,stdin);trueread(n) , read(m) , read(Q) ;trueszblc = (int)pow(n,2.0/3.0)*.5 ;trueRep (i,1,m) read(v[i]) ;trueRep (i,1,n) read(w[i]) ;trueRep (i,2,n) {truetrueread(a) , read(b) ;truetrueAddEdge(a,b) , AddEdge(b,a) ;true}trueRep (i,1,n) read(col[i]) , last[i] = col[i] ;truecntblc = idx = dep[0] = ansnow = top = 0 ;truedfs(1,0) ;truecntblc ++ ;truewhile (top) belong[sta[top--]] = cntblc ;trueST() ;trueint totq = 0 , totc = 0 ;trueRep (i,1,Q) {truetrueread(cmd) , read(a) , read(b) ;truetrueif (cmd) {truetruetruetotq ++ ;truetruetrueif (belong[a] > belong[b]) std::swap(a,b) ;truetruetrueq[totq].lca = LCA(a,b) ;truetruetrueq[totq].id = totq , q[totq].u = a , q[totq].v = b ;truetruetrueq[totq].tim = totc ;truetrue} else {truetruetruetotc ++ ;truetruetruec[totc].pos = a ;truetruetruec[totc].from = last[a] ;truetruetruec[totc].to = last[a] = b ;truetrue}true}truetimnow = 1 ;truestd::sort(q+1,q+totq+1) ;truewhile (timnow <= q[1].tim) Modify(c[timnow].pos,c[timnow].to) , ++timnow ;trueMoveTo(q[1].u,q[1].v) ;trueGetAns(1) ;trueRep (i,2,totq) {truetruewhile (timnow <= q[i].tim) Modify(c[timnow].pos,c[timnow].to) , ++timnow ;truetruewhile (timnow-1 > q[i].tim) Modify(c[timnow-1].pos,c[timnow-1].from) , --timnow ;truetrueMoveTo(q[i-1].u,q[i].u) ;truetrueMoveTo(q[i-1].v,q[i].v) ;truetrueGetAns(i) ;true}trueRep (i,1,totq) print(ans[i]) ;truefwrite(chout,1,po-chout,stdout);true//printf("%.2lf\n",clock()/1000.0) ;true#ifdef READtruetruefclose(stdin) ; fclose(stdout) ;true#elsetruetruegetchar() ; getchar() ;true#endiftruereturn 0 ;}