bzoj2243: [SDOI2011]染色--线段树+树链剖分

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2243: [SDOI2011]染色--线段树+树链剖分相关的知识,希望对你有一定的参考价值。

此题代码量较大。。但是打起来很爽

原本不用lca做一直wa不知道为什么。。

后来改lca重打了一遍= =结果一遍就AC了orz

题目比较裸,也挺容易打,主要是因为思路可以比较清晰

另:加读入优化比没加快了1.3s。。

 

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 using namespace std;
  5 const int maxn = 100010;
  6 struct node{
  7     int l,r,lc,rc,sum,lz;
  8 }t[maxn*4];
  9 struct edge{
 10     int to,next;
 11 }e[maxn*2];
 12 int n,m,u,v,tot,cnt,logn=0;
 13 int head[maxn],son[maxn],pre[maxn],tree[maxn],top[maxn],dep[maxn],fa[maxn][30],size[maxn],col[maxn];
 14 
 15 inline void read(int &x){
 16     char cc=getchar(); x=0; int f=1;
 17     while (cc<0 || cc>9){if (cc==-) f=-1; cc=getchar();}
 18     while (cc>=0 && cc<=9) x=x*10+cc-0,cc=getchar(); x*=f;
 19 }
 20 
 21 inline void insert(int u, int v){
 22     e[++tot].to=v; e[tot].next=head[u]; head[u]=tot;
 23 }
 24 
 25 inline void dfs1(int u, int f, int d){
 26     size[u]=1; fa[u][0]=f; dep[u]=d;
 27     for (int i=1; i<=logn; i++) fa[u][i]=fa[fa[u][i-1]][i-1];
 28     for (int i=head[u]; i!=-1; i=e[i].next){
 29         int v=e[i].to;
 30         if (v==f) continue;
 31         dfs1(v,u,d+1);
 32         size[u]+=size[v];
 33         if (!son[u] || size[v]>size[son[u]]) son[u]=v;
 34     }
 35 }
 36 
 37 inline void dfs2(int u, int num){
 38     top[u]=num; tree[u]=++cnt;
 39     pre[cnt]=u;
 40     if (!son[u]) return;
 41     dfs2(son[u],num);
 42     for (int i=head[u]; i!=-1; i=e[i].next)
 43         if (e[i].to!=fa[u][0] && e[i].to!=son[u])
 44             dfs2(e[i].to,e[i].to);
 45 }
 46 
 47 inline int lca(int u, int v){
 48     if (dep[u]>dep[v]) swap(u,v);
 49     while (dep[u]<dep[v]){
 50         for (int i=logn; i>=0; i--)
 51             if (dep[u]<dep[fa[v][i]])
 52                 v=fa[v][i];
 53         v=fa[v][0];
 54     }
 55     if (u==v) return u;
 56     for (int i=logn; i>=0; i--)
 57         if (fa[u][i]!=fa[v][i]){
 58             u=fa[u][i];
 59             v=fa[v][i];
 60         }
 61     u=fa[u][0];
 62     return u;
 63 }
 64 
 65 inline void pushdown(int x){
 66     if (t[x].lz){
 67         t[x<<1].lz=t[x<<1|1].lz=t[x].lz;
 68         t[x<<1].lc=t[x<<1].rc=t[x<<1|1].lc=t[x<<1|1].rc=t[x].lz;
 69         t[x<<1].sum=t[x<<1|1].sum=1;
 70         t[x].lz=0;
 71     }
 72 }
 73 
 74 inline void pushup(int x){
 75     t[x].lc=t[x<<1].lc; t[x].rc=t[x<<1|1].rc;
 76     t[x].sum=t[x<<1].sum+t[x<<1|1].sum-(t[x<<1].rc==t[x<<1|1].lc);
 77 }
 78 
 79 inline int query(int a, int b, int x){
 80     int l=t[x].l, r=t[x].r;
 81     if (a==l && r==b) return t[x].sum;
 82     int mid=l+r>>1;
 83     pushdown(x);
 84     if (b<=mid) return query(a,b,x<<1);
 85     else if (a>mid) return query(a,b,x<<1|1);
 86     else return query(a,mid,x<<1)+query(mid+1,b,x<<1|1)-(t[x<<1].rc==t[x<<1|1].lc);
 87 }
 88 
 89 inline void update(int a, int b, int c, int x){
 90     int l=t[x].l, r=t[x].r;
 91     if (a==l && r==b){
 92         t[x].lc=t[x].rc=t[x].lz=c;
 93         t[x].sum=1;
 94         return;
 95     }
 96     int mid=l+r>>1;
 97     pushdown(x);
 98     if (b<=mid) update(a,b,c,x<<1);
 99     else if (a>mid) update(a,b,c,x<<1|1);
100     else{
101         update(a,mid,c,x<<1);
102         update(mid+1,b,c,x<<1|1);
103     }
104     pushup(x);
105 }
106 
107 inline int get_col(int a, int x){
108     int l=t[x].l, r=t[x].r;
109     if (l==r) return t[x].lc;
110     pushdown(x);
111     int mid=l+r>>1;
112     if (a<=mid) return get_col(a,x<<1);
113     else return get_col(a,x<<1|1);
114 }
115 
116 inline void build(int l, int r, int x){
117     t[x].l=l; t[x].r=r;
118     if (l==r){
119         t[x].lc=t[x].rc=col[pre[l]];
120         t[x].sum=1;
121         return;
122     }
123     int mid=l+r>>1;
124     if (l<=mid) build(l,mid,x<<1);
125     if (r>mid) build(mid+1,r,x<<1|1);
126     pushup(x);
127 }
128 
129 inline void change(int x, int f, int c){
130     while (top[x]!=top[f]){
131         update(tree[top[x]],tree[x],c,1);
132         x=fa[top[x]][0];
133     }
134     update(tree[f],tree[x],c,1);
135 }
136 
137 inline int get_sum(int x, int f){
138     int res=0;
139     while (top[x]!=top[f]){
140         res+=query(tree[top[x]],tree[x],1);
141         if (get_col(tree[top[x]],1)==get_col(tree[fa[top[x]][0]],1)) res--;
142         x=fa[top[x]][0];
143     }
144     res+=query(tree[f],tree[x],1);
145     return res;
146 }
147 
148 int main(){
149     read(n); read(m);
150     while ((1<<logn)<n) logn++;
151     for (int i=1; i<=n; i++) read(col[i]),col[i]++;
152     tot=-1; memset(head,-1,sizeof(head));
153     for (int i=1; i<n; i++){
154         read(u); read(v);
155         insert(u,v); insert(v,u);
156     }
157     cnt=0;
158     dfs1(1,0,1); dfs2(1,0);
159     build(1,n,1);
160     char s[5];
161     while (m--){
162         scanf("%s", s);
163         if (s[0]==Q){
164             read(u); read(v);
165             int t=lca(u,v);
166             printf("%d\n", get_sum(u,t)+get_sum(v,t)-1);
167         }
168         else{
169             int color;
170             read(u); read(v); read(color);
171             int t=lca(u,v);
172             color++;
173             change(u,t,color);
174             change(v,t,color);
175         }
176     }
177     return 0;
178 }

 

以上是关于bzoj2243: [SDOI2011]染色--线段树+树链剖分的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ2243][SDOI2011]染色

BZOJ2243: [SDOI2011]染色

BZOJ2243: [SDOI2011]染色

bzoj 2243: [SDOI2011]染色

BZOJ2243: [SDOI2011]染色

BZOJ 2243 SDOI 2011染色