标签:
//Accepted 18440 KB 5556 ms /* source:HYSBZ 2243 time :2015.5.29 by :songt */ /*题解: 树链剖分 */ #include <cstdio> #include <cstring> const int imax_n = 100005; struct Edge { int u,v; Edge(){} Edge(int u,int v):u(u),v(v){} }edge[2*imax_n]; int head[imax_n]; int next[2*imax_n]; int tot; int top[imax_n]; int son[imax_n]; int num[imax_n]; int p[imax_n]; int fp[imax_n]; int deep[imax_n]; int fa[imax_n]; int pos; void init() { memset(head,-1,sizeof(head)); memset(next,-1,sizeof(next)); tot=0; memset(son,-1,sizeof(son)); pos=0; } void addEdge(int u,int v) { edge[tot]=Edge(u,v); next[tot]=head[u]; head[u]=tot++; } void dfs1(int u) { num[u]=1; for (int i=head[u];i+1;i=next[i]) { int v=edge[i].v; if (v!=fa[u]) { fa[v]=u; deep[v]=deep[u]+1; dfs1(v); num[u]+=num[v]; if (son[u]==-1 || num[son[u]]<num[v]) son[u]=v; } } } void dfs2(int u) { p[u]=pos++; fp[p[u]]=u; if (son[u]==-1) return ; top[son[u]]=top[u]; dfs2(son[u]); for (int i=head[u];i+1;i=next[i]) { int v=edge[i].v; if (v!=son[u] && v!=fa[u]) { dfs2(top[v]=v); } } } struct Tree { int l,r; int lc,rc; int num; int same; int color; }f[imax_n*3]; int color[imax_n]; void push_down(int t) { f[2*t].same=f[2*t+1].same=1; f[2*t].color=f[2*t+1].color=f[t].color; f[2*t].num=f[2*t+1].num=1; f[2*t].lc=f[2*t].rc=f[t].color; f[2*t+1].lc=f[2*t+1].rc=f[t].color; f[t].same=0; } void push_up(int t) { f[t].num=f[2*t].num+f[2*t+1].num-(f[2*t].rc==f[2*t+1].lc); f[t].lc=f[2*t].lc; f[t].rc=f[2*t+1].rc; } void build(int t,int l,int r) { f[t].l=l; f[t].r=r; f[t].same=0; if (l==r) { f[t].lc=f[t].rc=color[fp[l]]; f[t].color=color[fp[l]]; f[t].num=1; f[t].same=1; return ; } int mid=(f[t].l+f[t].r)>>1; build(2*t,l,mid); build(2*t+1,mid+1,r); push_up(t); } void update(int t,int l,int r,int color) { if (f[t].l==l && f[t].r==r) { f[t].color=color; f[t].num=1; f[t].lc=f[t].rc=color; f[t].same=1; return ; } if (f[t].same) push_down(t); int mid=(f[t].l+f[t].r)>>1; if (r<=mid) update(2*t,l,r,color); else { if (l>mid) update(2*t+1,l,r,color); else { update(2*t,l,mid,color); update(2*t+1,mid+1,r,color); } } push_up(t); } int query(int t,int l,int r,int &cl,int &rl) { if (f[t].l==l && f[t].r==r) { cl=f[t].lc; rl=f[t].rc; return f[t].num; } if (f[t].same) push_down(t); int mid=(f[t].l+f[t].r)>>1; if (r<=mid) return query(2*t,l,r,cl,rl); else { if (l>mid) return query(2*t+1,l,r,cl,rl); else { int lcl,lcr,rcl,rcr; int numl,numr; numl=query(2*t,l,mid,lcl,lcr); numr=query(2*t+1,mid+1,r,rcl,rcr); cl=lcl; rl=rcr; return numl+numr-(lcr==rcl); } } } void swap(int &a,int &b) { int t=a; a=b; b=t; } void OpC(int u,int v,int c) { int f1=top[u],f2=top[v]; while (f1!=f2) { //printf("u=%d v=%d top[u]=%d top[v]=%d\n",u,v,f1,f2); if (deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } update(1,p[f1],p[u],c); //printf("update %d %d\n",f1,u); u=fa[f1]; f1=top[u]; } if (deep[u]>deep[v]) swap(u,v); update(1,p[u],p[v],c); //printf("update %d %d\n",u,v); } int OpQ(int u,int v) { int f1=top[u],f2=top[v]; int cu=-1,cv=-1; int ans=0; int lc,rc; while (f1!=f2) { if (deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); swap(cu,cv); } int tmp=query(1,p[f1],p[u],lc,rc); //printf("%d %d num=%d lc=%d rc=%d\n",f1,u,tmp,lc,rc); ans+=tmp; ans-=(cu==rc); cu=lc; u=fa[f1]; f1=top[u]; } if (deep[u]>deep[v]) { swap(u,v); swap(cu,cv); } int tmp=query(1,p[u],p[v],lc,rc); //printf("%d %d num=%d lc=%d rc=%d\n",u,v,tmp,lc,rc); ans+=query(1,p[u],p[v],lc,rc); ans-=(cu==lc); ans-=(cv==rc); return ans; } int n,m; char op[10]; int u,v,c; int main() { //while (scanf("%d%d",&n,&m)==2) scanf("%d%d",&n,&m); { init(); for (int i=1;i<=n;i++) { scanf("%d",&color[i]); } for (int i=0;i<n-1;i++) { scanf("%d%d",&u,&v); addEdge(u,v); addEdge(v,u); } fa[1]=0; deep[1]=0; dfs1(1); dfs2(top[1]=1); build(1,0,pos-1); for (int i=0;i<m;i++) { scanf("%s",op); if (op[0]==‘Q‘) { scanf("%d%d",&u,&v); printf("%d\n",OpQ(u,v)); } else { scanf("%d%d%d",&u,&v,&c); OpC(u,v,c); } } } return 0; }
标签:
原文地址:http://www.cnblogs.com/djingjing/p/4539287.html