1. 程式人生 > >[SDOI2011]染色

[SDOI2011]染色

i++ load col == alt 標記 染色 iostream d+

題目描述

技術分享

輸入輸出格式

輸入格式:

技術分享

輸出格式:

對於每個詢問操作,輸出一行答案。

輸入輸出樣例

輸入樣例#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]染色