首页 > 代码库 > [SDOI2011]染色

[SDOI2011]染色

题目描述

技术分享

输入输出格式

输入格式:

 

技术分享

 

输出格式:

 

对于每个询问操作,输出一行答案。

 

输入输出样例

输入样例#1:
6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
输出样例#1:
3
1
2

说明

技术分享

技术分享

题解:

线段树+树链划分

先将树拆成链,在用线段树维护区间的答案

难点就是怎么维护,还有一个问题如下:

树上的路径可能有多条线段构成,就算维护了区间的答案,还要把那些线段合并

维护方法,lx表示当前线段的左边颜色,rx同理,合并线段时,如果lson的rx=rson的lx则sum-1

每次查询完路径的一个树链后,判断链的上端点和其父节点的颜色,若相同,则ans-1

修改用lazy标记就行

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 struct Node
  7 {
  8     int next,to;
  9 }edge[200001];
 10 int head[100001],num,son[100001],size[100001],s[400001],lx[400001],rx[400001],pos[100001];
 11 int top[100001],fa[100001],dep[100001],tot,sgm[100001],color[100001],lazy[400001],n,m;
 12 char get_op()
 13 {
 14     char ch=getchar();
 15     while (ch!=C&&ch!=Q) ch=getchar();
 16     return ch;
 17 }
 18 void add(int u,int v)
 19 {
 20     num++;
 21     edge[num].next=head[u];
 22     head[u]=num;
 23     edge[num].to=v;
 24 }
 25 void dfs1(int u,int pa)
 26 {int i;
 27     size[u]=1;
 28     dep[u]=dep[pa]+1;
 29     fa[u]=pa;
 30     for(int i=head[u]; i; i=edge[i].next)
 31     {
 32         int v=edge[i].to;
 33         if(v==pa)continue;
 34         dfs1(v,u);
 35         size[u]+=size[v];
 36         if(size[v]>size[son[u]])son[u]=v;
 37     }
 38 }
 39 void dfs2(int u,int pa,int tp)
 40 {int i;
 41     pos[u]=++tot;
 42     sgm[tot]=u;
 43     top[u]=tp;
 44     if(son[u]) dfs2(son[u],u,tp);
 45     for(int i=head[u]; i; i=edge[i].next)
 46     {
 47         int v=edge[i].to;
 48         if(v==pa||v==son[u])continue;
 49         dfs2(v,u,v);
 50     }
 51 }
 52 void pushdown(int rt)
 53 {
 54     if (lazy[rt]!=-1)
 55     {
 56         lazy[rt*2]=lazy[rt];
 57         lazy[rt*2+1]=lazy[rt];
 58         lx[rt*2]=lx[rt*2+1]=rx[rt*2]=rx[rt*2+1]=lazy[rt];
 59         s[rt*2+1]=s[rt*2]=1;
 60         lazy[rt]=-1;
 61     }
 62 }
 63 void pushup(int rt)
 64 {
 65      lx[rt]=lx[rt*2];
 66      rx[rt]=rx[rt*2+1]; 
 67      s[rt]=s[rt*2]+s[rt*2+1];
 68     if (lx[rt*2+1]==rx[rt*2]) s[rt]--;
 69 }
 70 void build(int rt,int l,int r)
 71 {lazy[rt]=-1;
 72     if (l==r)
 73     {
 74         s[rt]=1;
 75         lx[rt]=rx[rt]=color[sgm[l]];
 76         //cout<<sgm[l]<<‘ ‘<<l<<endl;
 77         return;
 78     }
 79      int mid=(l+r)/2;
 80      build(rt*2,l,mid);
 81      build(rt*2+1,mid+1,r);
 82      pushup(rt);
 83 }
 84 int query(int rt,int l,int r,int L,int R)
 85 {int ans=0;
 86     if (l==L&&r==R)
 87     {
 88         return s[rt];
 89     }
 90     pushdown(rt);
 91     int mid=(l+r)/2;
 92      if (L>mid) return query(rt*2+1,mid+1,r,L,R);
 93      else if (R<=mid) return query(rt*2,l,mid,L,R);
 94      else 
 95      {
 96          ans=query(rt*2,l,mid,L,mid)+query(rt*2+1,mid+1,r,mid+1,R);
 97           if (lx[rt*2+1]==rx[rt*2]) ans--;
 98           return ans;
 99       } 
100 }
101 void update(int rt,int l,int r,int L,int R,int d)
102 {
103     if (l==L&&r==R)
104     {
105         s[rt]=1;
106         lx[rt]=rx[rt]=d;
107         lazy[rt]=d;
108         return;
109     }
110     pushdown(rt);
111     int mid=(l+r)/2;
112     if(L>mid)update(rt*2+1,mid+1,r,L,R,d);
113     else if(R<=mid)update(rt*2,l,mid,L,R,d);
114     else update(rt*2,l,mid,L,mid,d),update(rt*2+1,mid+1,r,mid+1,R,d);
115     pushup(rt);
116 }
117 void change(int x,int y,int d)
118 {
119      while (top[x]!=top[y])
120     {
121         if (dep[top[x]]<dep[top[y]]) swap(x,y);
122         update(1,1,tot,pos[top[x]],pos[x],d);
123         x=fa[top[x]];
124     }
125     if (dep[x]>dep[y]) swap(x,y);
126      update(1,1,tot,pos[x],pos[y],d);
127 }
128 int query_color(int rt,int l,int r,int x)
129 {
130     if (l==r)
131     {
132         return lx[rt];
133     }
134     pushdown(rt);
135     int mid=(l+r)/2;
136      if (x<=mid) return query_color(rt*2,l,mid,x);
137      else return query_color(rt*2+1,mid+1,r,x);
138 }
139 int ask(int x,int y)
140 {
141     int ans=0;
142      while (top[x]!=top[y])
143     {
144         if (dep[top[x]]<dep[top[y]]) swap(x,y);
145         ans+=query(1,1,tot,pos[top[x]],pos[x]);
146         int p1=query_color(1,1,tot,pos[top[x]]);
147         int p2=query_color(1,1,tot,pos[fa[top[x]]]);
148         //cout<<x<<‘ ‘<<y<<‘ ‘<<ans<<endl;
149         x=fa[top[x]];
150         if (p1==p2) ans--;
151     }
152     if (dep[x]>dep[y]) swap(x,y);
153     ans+=query(1,1,tot,pos[x],pos[y]);
154     if (ans==0) return 1;
155 return ans;
156 }
157 int main()
158 {int i,j,x,y,c;
159 char opt;
160     cin>>n>>m;
161     memset(lazy,-1,sizeof(lazy));
162     for (i=1;i<=n;i++)
163     {
164         scanf("%d",&color[i]);
165     }
166      for (i=1;i<=n-1;i++)
167      {
168          scanf("%d%d",&x,&y);
169          add(x,y);
170          add(y,x);
171      }
172      dfs1(1,1);
173      dfs2(1,1,1);
174      build(1,1,tot);
175      for (i=1;i<=m;i++)
176      {
177          opt=get_op();
178          if (opt==Q)
179          {
180              scanf("%d%d",&x,&y);
181              printf("%d\n",ask(x,y));
182         }
183         else 
184         {
185             scanf("%d%d",&x,&y,&c);
186             change(x,y,c);
187         }
188      }
189 }

 

[SDOI2011]染色