B20J_2243_[SDOI2011]染色_树链剖分+线段树
一下午净调这题了,争取晚上多做几道。
题意:
给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),
如“112221”由3段组成:“11”、“222”和“1”。
分析:
线段树结点维护信息:区间内颜色段数t ,区间左端点颜色lco,区间右端点颜色rco,延迟标记lazy
上传时lco[pos]=lco[lson];rco[pos]=rco[rson];t[pos]=t[lson]+t[rson];如果左区间右端点和右区间左端点颜色相同,t[pos]--;
查询时每次找到左右端点的颜色(直接单点查找),如果LC=RC,ans--;
注意每次标记下传的时机。
代码
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 #define N 1000010 6 #define M 2062145 7 #define lson pos<<1 8 #define rson pos<<1|1 9 int head[N],to[N<<1],nxt[N<<1],co[N],cnt,n,m,scc; 10 char ch[10]; 11 int dep[N],fa[N],siz[N],son[N],top[N]; 12 int t[M],lzy[M],idx[N],lco[M],rco[M],a[N]; 13 inline void read(int &x) 14 { 15 int f=1;x=0;char s=getchar(); 16 while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();} 17 while(s>=‘0‘&&s<=‘9‘){x=(x<<3)+(x<<1)+s-‘0‘;s=getchar();} 18 x*=f; 19 } 20 inline void add(int u,int v) 21 { 22 to[++cnt]=v; 23 nxt[cnt]=head[u]; 24 head[u]=cnt; 25 } 26 inline void dfs1(int x,int y) 27 { 28 dep[x]=dep[y]+1; 29 fa[x]=y; 30 siz[x]=1; 31 for(int i=head[x];i;i=nxt[i]) 32 { 33 if(to[i]!=y) 34 { 35 dfs1(to[i],x); 36 siz[x]+=siz[to[i]]; 37 if(siz[to[i]]>siz[son[x]]) 38 { 39 son[x]=to[i]; 40 } 41 } 42 } 43 } 44 inline void dfs2(int x,int t) 45 { 46 top[x]=t; 47 idx[x]=++scc; 48 if(son[x])dfs2(son[x],t); 49 for(int i=head[x];i;i=nxt[i]) 50 { 51 if(to[i]!=fa[x]&&to[i]!=son[x]) 52 { 53 dfs2(to[i],to[i]); 54 } 55 } 56 } 57 inline void pud(int pos) 58 { 59 if(!lzy[pos])return ; 60 t[lson]=1;lzy[lson]=lco[lson]=rco[lson]=lzy[pos]; 61 t[rson]=1;lzy[rson]=lco[rson]=rco[rson]=lzy[pos]; 62 lzy[pos]=0; 63 } 64 inline void up(int l,int r,int pos,int x,int y,int c) 65 { 66 if(x<=l&&y>=r) 67 { 68 t[pos]=1; 69 lco[pos]=c; 70 rco[pos]=c; 71 lzy[pos]=c; 72 return ; 73 } 74 pud(pos); 75 int mid=l+r>>1; 76 if(x<=mid)up(l,mid,lson,x,y,c); 77 if(y>mid)up(mid+1,r,rson,x,y,c); 78 t[pos]=t[lson]+t[rson]; 79 if(lco[rson]==rco[lson])t[pos]--; 80 lco[pos]=lco[lson]; 81 rco[pos]=rco[rson]; 82 } 83 inline int query(int l,int r,int pos,int x,int y) 84 { 85 pud(pos); 86 int re=0; 87 int mid=l+r>>1; 88 if(x<=l&&y>=r) 89 { 90 return t[pos]; 91 } 92 if(y<=mid) return query(l,mid,lson,x,y); 93 else if(x>mid) return query(mid+1,r,rson,x,y); 94 else 95 { 96 re=query(l,mid,lson,x,y)+query(mid+1,r,rson,x,y); 97 if(lco[rson]==rco[lson])re--; 98 return re; 99 } 100 } 101 inline int col(int l,int r,int x,int pos) 102 { 103 pud(pos); 104 if(l==r)return lco[pos]; 105 int mid=l+r>>1; 106 if(x<=mid)return col(l,mid,x,lson); 107 else return col(mid+1,r,x,rson); 108 } 109 int main() 110 { 111 read(n),read(m); 112 int x,y,z; 113 register int i; 114 for(i=1;i<=n;++i) 115 { 116 read(a[i]); 117 } 118 for(i=1;i<n;++i) 119 { 120 read(x),read(y); 121 add(x,y); 122 add(y,x); 123 } 124 dfs1(1,0); 125 dfs2(1,1); 126 for(i=1;i<=n;++i)up(1,n,1,idx[i],idx[i],a[i]); 127 while(m--) 128 { 129 scanf("%s",ch); 130 if(ch[0]==‘C‘) 131 { 132 read(x),read(y),read(z); 133 while(top[x]!=top[y]) 134 { 135 if(dep[top[x]]>dep[top[y]])swap(x,y); 136 up(1,n,1,idx[top[y]],idx[y],z); 137 y=fa[top[y]]; 138 } 139 if(dep[x]<dep[y])swap(x,y); 140 up(1,n,1,idx[y],idx[x],z); 141 } 142 else 143 { 144 read(x),read(y); 145 int ans=0; 146 while(top[x]!=top[y]) 147 { 148 if(dep[top[x]]>dep[top[y]])swap(x,y); 149 int LC=col(1,n,idx[top[y]],1),RC=col(1,n,idx[fa[top[y]]],1); 150 ans+=query(1,n,1,idx[top[y]],idx[y]); 151 if(LC==RC)ans--; 152 y=fa[top[y]]; 153 } 154 if(dep[x]<dep[y])swap(x,y); 155 ans+=query(1,n,1,idx[y],idx[x]); 156 if(!ans)ans=1; 157 printf("%d\n",ans); 158 } 159 } 160 }