首页 > 代码库 > AC日记——[SDOI2011]染色 洛谷 P2486
AC日记——[SDOI2011]染色 洛谷 P2486
题目描述
输入输出格式
输入格式:
输出格式:
对于每个询问操作,输出一行答案。
输入输出样例
输入样例#1:
6 52 2 1 2 1 11 21 32 42 52 6Q 3 5C 2 1 1Q 3 5C 5 1 2Q 3 5
输出样例#1:
312
说明
思路:
树剖+线段树维护区间颜色数量
来,上代码:
#include <cstdio>#include <iostream>#include <algorithm>#define maxn 200001using namespace std;struct TreeNodeType { int l,r,dis,lc,rc,flag,mid;};struct TreeNodeType tree[maxn<<2];struct EdgeType { int to,next;};struct EdgeType edge[maxn<<1];int n,m,if_z,dis[maxn],flag[maxn],dis_[maxn];int size[maxn],head[maxn],deep[maxn],f[maxn];int cnt,tot,num,belong[maxn];char Cget;inline void read_int(int &now){ now=0,if_z=1,Cget=getchar(); while(Cget>‘9‘||Cget<‘0‘) { if(Cget==‘-‘) if_z=-1; Cget=getchar(); } while(Cget>=‘0‘&&Cget<=‘9‘) { now=now*10+Cget-‘0‘; Cget=getchar(); } now*=if_z;}inline void edge_add(int from,int to){ edge[++num].to=from,edge[num].next=head[to],head[to]=num; edge[++num].to=to,edge[num].next=head[from],head[from]=num;}void search(int now,int fa){ int pos=cnt++; deep[now]=deep[fa]+1,f[now]=fa; for(int i=head[now];i;i=edge[i].next) { if(edge[i].to==fa) continue; search(edge[i].to,now); } size[now]=cnt-pos;}void search_(int now,int chain){ belong[now]=chain,flag[now]=++cnt; dis_[flag[now]]=dis[now]; int pos=0; for(int i=head[now];i;i=edge[i].next) { if(edge[i].to==f[now]) continue; if(size[edge[i].to]>size[pos]) pos=edge[i].to; } if(pos!=0) search_(pos,chain); else return ; for(int i=head[now];i;i=edge[i].next) { if(edge[i].to==f[now]||edge[i].to==pos) continue; search_(edge[i].to,edge[i].to); }}inline void tree_up(int now){ if(tree[now<<1].rc==tree[now<<1|1].lc) { tree[now].dis=tree[now<<1].dis+tree[now<<1|1].dis-1; } else { tree[now].dis=tree[now<<1].dis+tree[now<<1|1].dis; } tree[now].lc=tree[now<<1].lc,tree[now].rc=tree[now<<1|1].rc;}inline void tree_down(int now){ if(tree[now].l==tree[now].r) return ; tree[now<<1].dis=1,tree[now<<1|1].dis=1; tree[now<<1].lc=tree[now<<1].rc=tree[now].flag; tree[now<<1|1].lc=tree[now<<1|1].rc=tree[now].flag; tree[now<<1].flag=tree[now<<1|1].flag=tree[now].flag; tree[now].flag=0;}void tree_build(int now,int l,int r){ tree[now].l=l,tree[now].r=r; if(l==r) { tree[now].lc=dis_[++cnt]; tree[now].rc=tree[now].lc; tree[now].dis=1; return ; } tree[now].mid=(l+r)>>1; tree_build(now<<1,l,tree[now].mid); tree_build(now<<1|1,tree[now].mid+1,r); tree_up(now);}void tree_change(int now,int l,int r,int x){ if(tree[now].l==l&&tree[now].r==r) { tree[now].dis=1,tree[now].flag=x; tree[now].lc=tree[now].rc=x; return ; } if(tree[now].flag) tree_down(now); if(l>tree[now].mid) tree_change(now<<1|1,l,r,x); else if(r<=tree[now].mid) tree_change(now<<1,l,r,x); else { tree_change(now<<1,l,tree[now].mid,x); tree_change(now<<1|1,tree[now].mid+1,r,x); } tree_up(now);}int tree_query(int now,int l,int r){ if(tree[now].l==l&&tree[now].r==r) { return tree[now].dis; } if(tree[now].flag) tree_down(now); tree_up(now); if(l>tree[now].mid) return tree_query(now<<1|1,l,r); else if(r<=tree[now].mid) return tree_query(now<<1,l,r); else { int ld=tree_query(now<<1,l,tree[now].mid); int rd=tree_query(now<<1|1,tree[now].mid+1,r); if(tree[now<<1].rc==tree[now<<1|1].lc) return ld+rd-1; else return ld+rd; }}int tree_query_color(int now,int to){ if(tree[now].l==tree[now].r&&tree[now].l==to) { return tree[now].lc; } if(tree[now].flag) tree_down(now); tree_up(now); if(to>tree[now].mid) return tree_query_color(now<<1|1,to); else return tree_query_color(now<<1,to);}inline void solve_change(int x,int y,int z){ while(belong[x]!=belong[y]) { if(deep[belong[x]]<deep[belong[y]]) swap(x,y); tree_change(1,flag[belong[x]],flag[x],z); x=f[belong[x]]; } tree_change(1,min(flag[x],flag[y]),max(flag[x],flag[y]),z);}inline int solve_query(int x,int y){ int ans=0; while(belong[x]!=belong[y]) { if(deep[belong[x]]<deep[belong[y]]) swap(x,y); ans+=tree_query(1,flag[belong[x]],flag[x]); if(tree_query_color(1,flag[belong[x]])==tree_query_color(1,flag[f[belong[x]]])) ans--; x=f[belong[x]]; } ans+=tree_query(1,min(flag[x],flag[y]),max(flag[x],flag[y])); return ans;}int main(){ read_int(n),read_int(m); for(int i=1;i<=n;i++) read_int(dis[i]); int from,to,pos; for(int i=1;i<n;i++) { read_int(from),read_int(to); edge_add(from,to); } search(1,0),cnt=0,search_(1,1),cnt=0,tree_build(1,1,n); char type; for(int i=1;i<=m;i++) { cin>>type; if(type==‘C‘) { read_int(from),read_int(to),read_int(pos); solve_change(from,to,pos); } else { read_int(from),read_int(to); printf("%d\n",solve_query(from,to)); } } return 0;}
AC日记——[SDOI2011]染色 洛谷 P2486
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。