bzoj2243 [SDOI2011]染色

题目链接

树上区间修改,用树链剖分+线段树

只是这个题合并的时候不好有点坑,调了半天

然后不知道为什么用现成的树剖求lca居然要T,改了倍增才过

 

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<string>
  7 #include<cmath>
  8 #include<ctime>
  9 #include<queue>
 10 #include<stack>
 11 #include<map>
 12 #include<set>
 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
 14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
 15 #define Clear(a,b) memset(a,b,sizeof(a))
 16 #define inout(x) printf("%d",(x))
 17 #define douin(x) scanf("%lf",&x)
 18 #define strin(x) scanf("%s",(x))
 19 #define LLin(x) scanf("%lld",&x)
 20 #define op operator
 21 #define CSC main
 22 typedef unsigned long long ULL;
 23 typedef const int cint;
 24 typedef long long LL;
 25 using namespace std;
 26 void inin(int &ret)
 27 {
 28     ret=0;int f=0;char ch=getchar();
 29     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
 30     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
 31     ret=f?-ret:ret;
 32 }
 33 int n,m,shen[100010],head[100010],next[200020],zhi[200020],col[100010],ed,son[100010],fa[100010],dfn[100010],tot,top[100010];
 34 int ft[100010][18];
 35 void dfs1(int x)
 36 {
 37     son[x]=1;
 38     for(int i=1;i<=17;i++)
 39     {
 40         if(shen[x]<(1<<i))break;
 41         ft[x][i]=ft[ft[x][i-1]][i-1];
 42     }
 43     for(int i=head[x];i;i=next[i])if(zhi[i]!=ft[x][0])
 44     {
 45         shen[zhi[i]]=shen[x]+1;
 46         ft[zhi[i]][0]=x;
 47         dfs1(zhi[i]);
 48         son[x]+=son[zhi[i]];
 49     }
 50 }
 51 void dfs2(int x,int chain)
 52 {
 53     dfn[x]=++tot;top[x]=chain;
 54     int k=0;
 55     for(int i=head[x];i;i=next[i])
 56         if(shen[zhi[i]]>shen[x]&&son[k]<son[zhi[i]])
 57            k=zhi[i];
 58     if(!k)return;
 59     dfs2(k,chain);
 60     for(int i=head[x];i;i=next[i])
 61         if(shen[zhi[i]]>shen[x]&&k!=zhi[i])
 62            dfs2(zhi[i],zhi[i]);
 63 }
 64 void add(int a,int b)
 65 {
 66     next[++ed]=head[a],head[a]=ed,zhi[ed]=b;
 67     next[++ed]=head[b],head[b]=ed,zhi[ed]=a;
 68 }
 69 struct segtree
 70 {
 71     int sum,lc,rc,l,r,add;
 72     segtree(){lc=rc=sum=0;}
 73 }t[400040];
 74 void build(int k,int l,int r)
 75 {
 76     t[k].l=l;t[k].r=r;t[k].sum=1;t[k].add=0;
 77     if(l==r)return;
 78     int mid=(l+r)>>1;
 79     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
 80 }
 81 void update(int k,int a,int x)
 82 {
 83     int l=t[k].l,r=t[k].r,mid=(l+r)>>1,p1=k<<1,p2=p1|1;
 84     if(l==r)
 85     {
 86         t[k].sum=1,t[k].lc=t[k].rc=x;
 87         return ;
 88     }
 89     if(a<=mid)update(p1,a,x);
 90     else update(p2,a,x);
 91     t[k].sum=t[p1].sum+t[p2].sum;
 92     if(t[p1].rc==t[p2].lc)t[k].sum--;
 93     t[k].lc=t[p1].lc,t[k].rc=t[p2].rc;
 94 }
 95 void down(int k)
 96 {
 97     if(!t[k].add)return ;
 98     int p1=k<<1,p2=p1|1;
 99     t[p1].add=t[p2].add=t[k].add;
100     t[p1].sum=t[p2].sum=1;
101     t[p1].lc=t[p1].rc=t[p2].lc=t[p2].rc=t[k].add;
102     t[k].add=0;
103     if(t[p1].l==t[p1].r)col[t[p1].l]=t[p1].add;
104     if(t[p2].l==t[p2].r)col[t[p2].l]=t[p2].add;
105 }
106 void change(int k,int x,int y,int c)
107 {
108     int l=t[k].l,r=t[k].r;
109     if(l==x&&r==y)
110     {t[k].lc=t[k].rc=c;t[k].sum=1;t[k].add=c;return;}
111     down(k);
112     int mid=(l+r)>>1;
113     if(mid>=y)change(k<<1,x,y,c);
114     else if(mid<x)change(k<<1|1,x,y,c);
115     else
116     {
117         change(k<<1,x,mid,c);
118         change(k<<1|1,mid+1,y,c);
119     }
120     t[k].lc=t[k<<1].lc;t[k].rc=t[k<<1|1].rc;
121     if(t[k<<1].rc^t[k<<1|1].lc)t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
122     else t[k].sum=t[k<<1].sum+t[k<<1|1].sum-1;
123 }
124 int query(int k,int x,int y)
125 {
126     int l=t[k].l,r=t[k].r;
127     if(l==x&&r==y)return t[k].sum;
128     down(k);
129     int mid=(l+r)>>1;
130     if(mid>=y)return query(k<<1,x,y);
131     else if(mid<x)return query(k<<1|1,x,y);
132     else
133     {
134         int tmp=1;
135         if(t[k<<1].rc^t[k<<1|1].lc)tmp=0;
136         return query(k<<1,x,mid)+query(k<<1|1,mid+1,y)-tmp;
137     }
138 }
139 //int lca(int x,int y)
140 //{
141 //    while(top[x]!=top[y])
142 //    {
143 //        if(shen[top[x]]>shen[top[y]])x=fa[top[x]];
144 //        else y=fa[top[y]];
145 //    }
146 //    return shen[x]>shen[y]?y:x;
147 //}
148 int lca(int x,int y)
149 {
150     if(shen[x]<shen[y])swap(x,y);
151     int t=shen[x]-shen[y];
152     for(int i=0;i<=17;i++)
153        if(t&(1<<i))x=ft[x][i];
154     for(int i=17;i>=0;i--)
155        if(ft[x][i]!=ft[y][i])
156        {x=ft[x][i];y=ft[y][i];}
157     if(x==y)return x;
158     return ft[x][0];
159 }
160 void change__(int x,int f,int c)
161 {
162     while(top[x]!=top[f])
163     {
164         change(1,dfn[top[x]],dfn[x],c);
165         x=ft[top[x]][0]; 
166     }
167     change(1,dfn[f],dfn[x],c);
168 }
169 int getc(int k,int x)
170 {
171     int l=t[k].l,r=t[k].r;
172     if(l==r)return t[k].lc;
173     down(k);
174     int mid=(l+r)>>1;
175     if(x<=mid)return getc(k<<1,x);
176     else return getc(k<<1|1,x);
177 }
178 int ad(int x,int f)
179 {
180     int ret=0;
181     while(top[x]!=top[f])
182     {
183         ret+=query(1,dfn[top[x]],dfn[x]);
184         if(getc(1,dfn[top[x]])==getc(1,dfn[ft[top[x]][0]]))ret--;
185         x=ft[top[x]][0]; 
186     }
187     ret+=query(1,dfn[f],dfn[x]);
188     return ret;
189 }
190 int CSC()
191 {
192     freopen("in.in","r",stdin);
193     freopen("out.out","w",stdout);
194     inin(n);inin(m);
195     re(i,1,n)inin(col[i]);
196     re(i,1,n-1)
197     {
198         int q,w;
199         inin(q),inin(w);
200         add(q,w);
201     }
202     dfs1(1);
203     dfs2(1,1);
204     build(1,1,n);
205     for(int i=1;i<=n;i++)
206         change(1,dfn[i],dfn[i],col[i]);
207     re(i,1,m)
208     {
209         char opt[5];strin(opt);
210         if(opt[0]=='C')
211         {
212             int q,w,e;
213             inin(q),inin(w),inin(e);
214             int r=lca(q,w);
215             change__(q,r,e),change__(w,r,e);
216         }
217         if(opt[0]=='Q')
218         {
219             int q,w;
220             inin(q),inin(w);
221             int e=lca(q,w);
222             printf("%d\n",ad(q,e)+ad(w,e)-1);
223         }
224     }
225     return 0;
226 }

 

posted @ 2016-01-22 13:54  HugeGun  阅读(156)  评论(0编辑  收藏  举报