解题: SDOI 2011 染色

题面

强行把序列问题通过树剖套在树上。。。算了算是回顾了一下树剖的思想=。=

每次树上跳的时候注意跳的同时维护当前拼出来的左右两条链的靠上的端点,然后拼起来的时候讨论一下拼接点,最后一下左右两边的端点都要考虑

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 using namespace std;
  5 const int N=100005;
  6 struct a
  7 {
  8     int cnt;
  9     int lc,rc;
 10 };
 11 int num[N],nmb[N],val[4*N],lcol[4*N],rcol[4*N],laz[4*N];
 12 int siz[N],dep[N],anc[N],imp[N],top[N],dfn[N];
 13 int p[N],noww[2*N],goal[2*N];
 14 int n,m,t1,t2,t3,cnt,tot;
 15 char rd[2];
 16 void link(int f,int t)
 17 {
 18     noww[++cnt]=p[f];
 19     goal[cnt]=t,p[f]=cnt;
 20 }
 21 void DFS(int nde,int fth,int dth)
 22 {
 23     int tmp=0;
 24     siz[nde]=1,anc[nde]=fth,dep[nde]=dth;
 25     for(int i=p[nde];i;i=noww[i])
 26         if(goal[i]!=fth)
 27         {
 28             DFS(goal[i],nde,dth+1);
 29             siz[nde]+=siz[goal[i]];
 30             if(siz[goal[i]]>tmp)
 31                 tmp=siz[goal[i]],imp[nde]=goal[i];
 32         }
 33 }
 34 void MARK(int nde,int tpp)
 35 {
 36     dfn[nde]=++tot,nmb[tot]=num[nde],top[nde]=tpp;
 37     if(imp[nde])
 38     {
 39         MARK(imp[nde],tpp);
 40         for(int i=p[nde];i;i=noww[i])
 41             if(goal[i]!=anc[nde]&&goal[i]!=imp[nde])
 42                 MARK(goal[i],goal[i]);
 43     }
 44 }
 45 void pushup(int nde)
 46 {
 47     int ls=2*nde,rs=2*nde+1;
 48     lcol[nde]=lcol[ls],rcol[nde]=rcol[rs];
 49     val[nde]=val[ls]+val[rs]-(rcol[ls]==lcol[rs]);
 50 }
 51 void create(int nde,int l,int r)
 52 {
 53     if(l==r)
 54         val[nde]=1,lcol[nde]=rcol[nde]=nmb[l];
 55     else
 56     {
 57         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
 58         create(ls,l,mid),create(rs,mid+1,r);
 59         pushup(nde);
 60     }
 61 }
 62 void release(int nde,int l,int r)
 63 {
 64     if(laz[nde])
 65     {
 66         int ls=2*nde,rs=2*nde+1;
 67         laz[ls]=lcol[ls]=rcol[ls]=laz[nde];
 68         laz[rs]=lcol[rs]=rcol[rs]=laz[nde];
 69         val[ls]=val[rs]=1; laz[nde]=0;
 70     }
 71 }
 72 void change(int nde,int l,int r,int nl,int nr,int task)
 73 {
 74     if(l>nr||r<nl)
 75         return ;
 76     else if(l>=nl&&r<=nr)
 77         val[nde]=1,lcol[nde]=rcol[nde]=laz[nde]=task;
 78     else
 79     {
 80         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r);
 81         change(ls,l,mid,nl,nr,task),change(rs,mid+1,r,nl,nr,task);
 82         pushup(nde);
 83     }    
 84 }
 85 a query(int nde,int l,int r,int nl,int nr)
 86 {
 87     if(l>=nl&&r<=nr)
 88         return (a){val[nde],lcol[nde],rcol[nde]};
 89     else
 90     {
 91         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r); 
 92         if(nr<=mid) return query(ls,l,mid,nl,nr);
 93         if(nl>mid) return query(rs,mid+1,r,nl,nr);
 94         a r1=query(ls,l,mid,nl,nr),r2=query(rs,mid+1,r,nl,nr),ret;
 95         ret.lc=r1.lc,ret.rc=r2.rc,ret.cnt=r1.cnt+r2.cnt-(r1.rc==r2.lc);
 96         return ret;
 97     }    
 98 }
 99 void path_change(int x,int y,int v)
100 {
101     while(top[x]!=top[y])
102     {
103         if(dep[top[x]]<dep[top[y]]) swap(x,y);
104         change(1,1,n,dfn[top[x]],dfn[x],v); x=anc[top[x]];
105     }
106     if(dep[x]>dep[y]) swap(x,y);
107     change(1,1,n,dfn[x],dfn[y],v); return ;
108 }
109 int path_query(int x,int y)
110 {
111     int rt=0,ll=-1,rr=-1;
112     while(top[x]!=top[y])
113     {
114         if(dep[top[x]]<dep[top[y]]) swap(x,y),swap(ll,rr);
115         a ret=query(1,1,n,dfn[top[x]],dfn[x]); x=anc[top[x]];
116         rt+=ret.cnt-(ll==ret.rc); ll=ret.lc;
117     }
118     if(dep[x]>dep[y]) swap(x,y),swap(ll,rr);
119     a ret=query(1,1,n,dfn[x],dfn[y]); rt+=ret.cnt-(ll==ret.lc)-(rr==ret.rc); 
120     return rt;
121 }
122 int main ()
123 {
124     scanf("%d%d",&n,&m);
125     for(int i=1;i<=n;i++)
126         scanf("%d",&num[i]);
127     for(int i=1;i<n;i++)    
128         scanf("%d%d",&t1,&t2),link(t1,t2),link(t2,t1);
129     DFS(1,0,1); MARK(1,1); create(1,1,n);
130     while(m--)
131     {
132         scanf("%s",rd);
133         if(rd[0]=='C')
134             scanf("%d%d%d",&t1,&t2,&t3),path_change(t1,t2,t3);
135         else 
136             scanf("%d%d",&t1,&t2),printf("%d
",path_query(t1,t2));
137     }
138     return 0;
139 }
View Code
原文地址:https://www.cnblogs.com/ydnhaha/p/9743416.html