BZOJ 2243: [SDOI2011]染色 [树链剖分+细节]【数据结构】
来源:互联网 发布:农村淘宝评论在哪里 编辑:程序博客网 时间:2024/06/03 18:23
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243
————————————————————————————————————————————————
2243: [SDOI2011]染色
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 7492 Solved: 2803
[Submit][Status][Discuss]
Description
给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作。
Input
第一行包含2个整数n和m,分别表示节点数和操作数;
第二行包含n个正整数表示n个节点的初始颜色
下面 行每行包含两个整数x和y,表示x和y之间有一条无向边。
下面 行每行描述一个操作:
“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;
“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。
Output
对于每个询问操作,输出一行答案。
Sample Input
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
Sample Output
3
1
2
HINT
数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。
Source
第一轮day1
————————————————————————————————————————————————
在树上两点间的路上进行修改 那么就是树链剖分,
根据操作 是区间染色 所以要用线段树维护
注意在维护的时候线段树上的每个点要多维护一个最左边和最右边的颜色。
方便合并的时候计算颜色个数
然后就是注意颜色可能为0
lazy标记的时候改成-1, 习惯性的用0 WA到死啊。
附本题代码
————————————————————————————————————————
#include <bits/stdc++.h>using namespace std;const int N = 1e5+7;/***************************************/int n,m;int c[N];vector<int >G[N];int fa[N],sz[N],son[N],dep[N];int dfs1(int u,int f,int d){ fa[u]=f,sz[u]=1,son[u]=0,dep[u]=d; int gz = G[u].size(); for(int to,i=0;i<gz;i++){ to = G[u][i]; if(to==f) continue; dfs1(to,u,d+1); sz[u]+=sz[to]; if(sz[son[u]]<sz[to]) son[u]=to; }}int top[N],tree[N],pre[N],cnt;int dfs2(int u,int tp){ top[u]=tp,tree[u]=++cnt,pre[tree[u]]=u; if(son[u]) dfs2(son[u],tp); int gz = G[u].size(); for(int to,i=0;i<gz;i++){ to = G[u][i]; if(to==fa[u]||to==son[u])continue; dfs2(to,to); }}int sum[N<<2],lazy[N<<2],lc[N<<2],rc[N<<2];void pushup(int rt){ sum[rt] = sum[rt<<1]+sum[rt<<1|1]-(rc[rt<<1] == lc[rt<<1|1]); lc[rt]=lc[rt<<1],rc[rt]=rc[rt<<1|1];}void pushdown(int rt){ if(lazy[rt]!=-1){ lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt]; sum [rt<<1] = sum [rt<<1|1] = 1; lc[rt<<1] = rc[rt<<1] = lazy[rt]; lc[rt<<1|1] = rc[rt<<1|1] = lazy[rt]; lazy[rt]=-1; }}void build(int rt,int l,int r){ if(l==r){ sum[rt]=1,rc[rt]=lc[rt]=c[pre[l]]; return ; } int m = (r+l)>>1; build(rt<<1 ,l ,m); build(rt<<1|1,m+1,r); pushup(rt);}void update(int rt,int l,int r,int L,int R,int clr){ if(L<=l&&r<=R){ rc[rt]=lc[rt]=lazy[rt]=clr; sum[rt] = 1; return ; } pushdown(rt); int m = (r+l)>>1; if(L<=m) update(rt<<1 ,l ,m,L,R,clr); if(R> m) update(rt<<1|1,m+1,r,L,R,clr); pushup(rt); return ;}int query(int rt,int l,int r,int L,int R){ if(L>R) return 0; if(L<=l&&r<=R) return sum[rt]; pushdown(rt); int ans = 0,m = (r+l)>>1; if(R<=m) ans = query(rt<<1 ,l, m,L,R); else if(L>m) ans = query(rt<<1|1,m+1,r,L,R); else ans = query(rt<<1 ,l, m,L,R)+ query(rt<<1|1,m+1,r,L,R)- (rc[rt<<1]==lc[rt<<1|1]); pushup(rt); return ans;}int query_color(int rt,int l,int r,int pos){ if(l==r) return lc[rt]; pushdown(rt); int m = (r+l)>>1,ans; if(pos<=m) ans = query_color(rt<<1 ,l ,m,pos); else ans = query_color(rt<<1|1,m+1,r,pos); pushup(rt); return ans;}void init(){ cnt = 0; for(int i=1;i<=n;i++)G[i].clear(); memset(sum,0,sizeof(sum)); memset(lazy,-1,sizeof(lazy));};void brush(int x,int y,int clr){ int fx = top[x],fy = top[y]; while(fx!=fy){ if(dep[fx]<dep[fy]) swap(fx,fy),swap(x,y); update(1,1,n,tree[fx],tree[x],clr); x = fa[fx],fx = top[x]; } if(tree[x]>tree[y]) swap(x,y); update(1,1,n,tree[x],tree[y],clr); return ;}void solve(int x,int y){ int fx = top[x],fy = top[y]; int ans = 0; while(fx!=fy){ if(dep[fx]<dep[fy]) swap(fx,fy),swap(x,y); ans += query(1,1,n,tree[fx],tree[x]); if(query_color(1,1,n,tree[fa[fx]]) == query_color(1,1,n,tree[fx])) ans--; x = fa[fx],fx = top[x]; } if(tree[x]>tree[y]) swap(x,y); ans += query(1,1,n,tree[x],tree[y]); printf("%d\n",ans); return ;}int main(){ while(~scanf("%d%d",&n,&m)){ init(); for(int i=1;i<=n;i++) scanf("%d",&c[i]); for(int i=2,u,v;i<=n;i++){ scanf("%d %d",&u,&v); G[u].push_back(v); G[v].push_back(u); } dfs1(1,-1,1); dfs2(1,1); build(1,1,n); int l,r,x; char a[10]; while(m--){ scanf("%s",a); scanf("%d %d",&l,&r); if(a[0]=='C'){ scanf("%d",&x); brush(l,r,x); } else solve(l,r); } } return 0;}
- BZOJ 2243: [SDOI2011]染色 [树链剖分+细节]【数据结构】
- 【BZOJ】2243 [SDOI2011]染色 树链剖分
- BZOJ 2243 SDOI2011 染色 树链剖分
- BZOJ 2243 [SDOI2011] 染色 (树链剖分)
- BZOJ 2243: [SDOI2011]染色 【树链剖分】
- BZOJ-2243: [SDOI2011]染色-树链剖分
- BZOJ 2243: [SDOI2011]染色 树链剖分
- BZOJ 2243: [SDOI2011]染色 树链剖分
- 【BZOJ】2243 [SDOI2011]染色 树链剖分
- bzoj 2243:[SDOI2011]染色 树链剖分
- 【BZOJ - 2243】 SDOI2011 染色
- BZOJ 2243: [SDOI2011]染色
- 【BZOJ 2243】 [SDOI2011]染色
- bzoj 2243: [SDOI2011]染色
- bzoj 2243: [SDOI2011]染色
- 【BZOJ 2243】[SDOI2011]染色
- BZOJ 2243 [SDOI2011] 染色
- bzoj 2243: [SDOI2011]染色
- opencv连续读取文件夹下的图片(python)
- UESTC 1060 秋实大哥与快餐店(字典树)
- 用Condition实现线程间高效通信
- 【BZOJ】3670 [Noi2014]动物园 KMP
- HDU-2017-字符串统计
- BZOJ 2243: [SDOI2011]染色 [树链剖分+细节]【数据结构】
- C++ SIGSEGV check list
- [转]ubuntu vivado hardware manager 找不到板子,要安装JTAG驱动
- “玲珑杯”第九届郑州轻工业学院校赛模拟赛部分题目题解
- STL库之queue队列使用
- KMP算法详解与例题汇总
- IMWeb前端学习笔记——Day4
- 工厂方法模式(Factory Method Pattern)
- 数据结构与算法---汉诺塔