LOJ10141染色
SDOI 2011 染色
给定一棵有 n 个节点的无根树和 m 个操作,操作共两类。
将节点 a 到节点 b 路径上的所有节点都染上颜色;
询问节点 a 到节点 b 路径上的颜色段数量,连续相同颜色的认为是同一段,例如 112221 由三段组成:11 、 222、1。
请你写一个程序依次完成操作。
输入格式
第一行包括两个整数 n,m,表示节点数和操作数;
第二行包含 n 个正整数表示 n 个节点的初始颜色;
接下来若干行包含两个整数 x 和 y,表示 x 和 y 之间有一条无向边;
接下来若干行每行描述一个操作:
C a b c 表示这是一个染色操作,把节点 a 到节点 b 路径上所有点(包括 a 和 b)染上颜色;
Q a b 表示这是一个询问操作,把节点 a 到节点 b 路径上(包括 a 和 b)的颜色段数量。
输出格式
对于每个询问操作,输出一行询问结果。
样例
样例输入
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
样例输出
3
1
2
数据范围与提示
对于 100% 的数据,N,M≤10^5, 所有颜色 C 为整数且在 [0,10^9] 之间。
_____________________________________________________________________________________
树链剖分,需要维护
sum[]:表示段内的色段数
lc[]:表示左侧点的颜色
rc[]:表示右侧点的颜色
所以,
sum[cur]=sum[cur<<1]+sum[cur<<1|1]-(rc[cur<<1]==lc[cur<<1|1])
lc[cur]=lc[cur<<1]
rc[cur]=rc[cur<<1|1]
需要注意,树链之间两点的颜色是否相同。
———————————————————————————————————————————————
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int maxn=1e5+10;
4 int n,m;
5 struct edge
6 {
7 int u,v,nxt;
8 }e[maxn<<1];
9 int head[maxn],js;
10 void addage(int u,int v)
11 {
12 e[++js].u=u;e[js].v=v;
13 e[js].nxt=head[u];head[u]=js;
14 }
15 int w[maxn];
16 int dep[maxn],fat[maxn],son[maxn],siz[maxn];
17 void dfs(int u,int fa)
18 {
19 dep[u]=dep[fa]+1;
20 fat[u]=fa;
21 siz[u]=1;
22 for(int i=head[u];i;i=e[i].nxt)
23 {
24 int v=e[i].v;
25 if(v==fa)continue;
26 dfs(v,u);
27 siz[u]+=siz[v];
28 if(!son[u] || siz[son[u]]<siz[v])son[u]=v;
29 }
30 }
31 int pos[maxn],fos[maxn],top[maxn],p;
32 void getpos(int u,int fa)
33 {
34 pos[u]=++p;
35 fos[p]=u;
36 top[u]=fa;
37 if(!son[u])return;
38 getpos(son[u],fa);
39 for(int i=head[u];i;i=e[i].nxt)
40 {
41 int v=e[i].v;
42 if(v!=fat[u] && v!=son[u])getpos(v,v);
43 }
44 }
45 int sum[maxn<<2],lc[maxn<<2],rc[maxn<<2],delt[maxn<<2];
46 void update(int cur)
47 {
48 lc[cur]=lc[cur<<1];
49 rc[cur]=rc[cur<<1|1];
50 sum[cur]=sum[cur<<1]+sum[cur<<1|1]-(rc[cur<<1]==lc[cur<<1|1]);
51 }
52 void build(int cur,int l,int r)
53 {
54 if(l==r)
55 {
56 lc[cur]=rc[cur]=w[fos[l]];
57 sum[cur]=1;
58 return;
59 }
60 int mid=(l+r)>>1;
61 build(cur<<1,l,mid);
62 build(cur<<1|1,mid+1,r);
63 update(cur);
64 }
65 void down(int cur)
66 {
67 sum[cur<<1]=sum[cur<<1|1]=1;
68 delt[cur<<1]=delt[cur<<1|1]=lc[cur<<1]=rc[cur<<1]=lc[cur<<1|1]=rc[cur<<1|1]=delt[cur];
69 delt[cur]=-1;
70 }
71 void modi(int cur,int l,int r,int ql,int qr,int x)
72 {
73 if(ql<=l && r<=qr)
74 {
75 sum[cur]=1;
76 delt[cur]=lc[cur]=rc[cur]=x;
77 return ;
78 }
79 int mid=(l+r)>>1;
80 if(delt[cur]!=-1)down(cur);
81 if(ql<=mid)modi(cur<<1,l,mid,ql,qr,x);
82 if(mid<qr)modi(cur<<1|1,mid+1,r,ql,qr,x);
83 update(cur);
84 }
85 void change(int u,int v,int x)
86 {
87 int tpu=top[u],tpv=top[v];
88 while(tpu!=tpv)
89 {
90 if(dep[tpu]<dep[tpv])
91 {
92 swap(u,v);swap(tpu,tpv);
93 }
94 modi(1,1,n,pos[tpu],pos[u],x);
95 u=fat[tpu];tpu=top[u];
96 }
97 if(dep[u]>dep[v])swap(u,v);
98 modi(1,1,n,pos[u],pos[v],x);
99 }
100 int query_c(int cur,int l,int r,int p)
101 {
102 if(l==r)return lc[cur];
103 int mid=(l+r)>>1;
104 if(delt[cur]!=-1)down(cur);
105 if(p<=mid)return query_c(cur<<1,l,mid,p);
106 else return query_c(cur<<1|1,mid+1,r,p);
107 }
108 int query(int cur,int l,int r,int ql,int qr)
109 {
110 if(ql<=l && r<=qr)return sum[cur];
111 int mid=(l+r)>>1,ans=0;
112 if(delt[cur]!=-1)down(cur);
113 if(ql<=mid)ans+=query(cur<<1,l,mid,ql,qr);
114 if(qr>mid)ans+=query(cur<<1|1,mid+1,r,ql,qr);
115 if(ql<=mid && mid<qr)ans-=rc[cur<<1]==lc[cur<<1|1];
116 return ans;
117 }
118 int ask(int u,int v)
119 {
120 int ans=0;
121 int clt,clp;
122 int tpu=top[u],tpv=top[v];
123 while(tpu!=tpv)
124 {
125 if(dep[tpu]<dep[tpv])
126 {
127 swap(u,v);swap(tpu,tpv);
128 }
129 clt=query_c(1,1,n,pos[tpu]);
130 clp=query_c(1,1,n,pos[fat[tpu]]);
131 ans+=query(1,1,n,pos[tpu],pos[u])-(clt==clp);
132 u=fat[tpu];tpu=top[u];
133 }
134 if(dep[u]>dep[v])swap(u,v);
135 ans+=query(1,1,n,pos[u],pos[v]);
136 return ans;
137 }
138 int main()
139 {
140 scanf("%d%d",&n,&m);
141 for(int i=1;i<=n;++i)scanf("%d",w+i);
142 for(int u,v,i=1;i<n;++i)
143 {
144 scanf("%d%d",&u,&v);
145 addage(u,v);addage(v,u);
146 }
147 dfs(1,0);
148 getpos(1,1);
149 memset(delt,-1,sizeof(delt));
150 build(1,1,n);
151 char s[3];
152 int a,b,c;
153 while(m--)
154 {
155 scanf("%s",s);
156 if(s[0]=='C')
157 {
158 scanf("%d%d%d",&a,&b,&c);
159 change(a,b,c);
160 }
161 else
162 {
163 scanf("%d%d",&a,&b);
164 printf("%d\n",ask(a,b));
165 }
166 }
167 return 0;
168 }
LOJ10141染色的更多相关文章
- bzoj2243树链剖分+染色段数
终于做了一道不是一眼出思路的代码题(⊙o⊙) 之前没有接触过这种关于染色段数的题目(其实上课好像讲过),于是百度了一下(现在思维能力好弱) 实际上每一段有用的信息就是总共有几段和两段各是什么颜色,在开 ...
- 51nod 算法马拉松18 A 染色问题
染色问题 基准时间限制:1 秒 空间限制:10240 KB 分值: 40 一个n(3<=n<=100)个点的完全图,现在给出n,要求将每条边都染上一种颜色k(1<=k<=n), ...
- BZOJ 2243: [SDOI2011]染色 [树链剖分]
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6651 Solved: 2432[Submit][Status ...
- NOIP2008双栈排序[二分图染色|栈|DP]
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- 洛谷P1330封锁阳光大学[二分图染色]
题目描述 曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街.河蟹看到欢快的曹,感到不爽.河蟹决定封锁阳光大学,不让曹刷街. 阳光大学的校园是一张由N个点构成的无向图,N个点之间由M ...
- POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 12439 Acce ...
- NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...
- POJ1112 Team Them Up![二分图染色 补图 01背包]
Team Them Up! Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7608 Accepted: 2041 S ...
- UVALive 4849 String Phone(2-sat、01染色)
题目一眼看去以为是4-sat... 题意:给n(n<=3000)个黑方块的坐标,保证黑方块没有公共边.对于每个黑方块选一个角作为结点,使得所选结点满足输入的一个无向图.其中距离为曼哈顿距离.输出 ...
随机推荐
- postgre sql递归查询
WITH RECURSIVE r AS (SELECT * FROM [表] WHERE id = xxxunion ALLSELECT [表].* FROM [表], r WHERE [表]. ...
- MySQL中的排序
在编写SQL 语句时常常会用到 order by 进行排序,那么排序过程是什么样的?为什么有些排序执行比较快,有些排序执行很慢?又该如何去优化? 索引排序 索引排序指的是在通过索引查询时就完成了排序, ...
- sendfile“零拷贝”和mmap内存映射
在学习sendfille之前,我们先来了解一下浏览器访问页面时,后台服务器的大致工作流程. 下图是从用户访问某个页面到页面的显示这几秒钟的时间当中,在后台的整个工作过程. 如上图,黑色箭头所示的过程, ...
- VScode中配置C++运行环境
目录 VScode中配置C++运行环境 1. 哪些插件 2. 配置开始 3. 编写代码并运行 VScode中配置C++运行环境 关于安装mingw的教程,网络上已经有很多了,这里不再赘述,下面就看VS ...
- JavaCV FFmpeg采集麦克风PCM音频数据
前阵子用一个JavaCV的FFmpeg库实现了YUV视频数据地采集,同样的采集PCM音频数据也可以采用JavaCV的FFmpeg库. 传送门:JavaCV FFmpeg采集摄像头YUV数据 首先引入 ...
- b站视频下载技术分享
最近无聊分析了一下b站的视频流协议,简单分享下爬取的流程. 首先先要找到视频对应的aid和cid,aid就相当于av号,而av号对应网页下的每一个视频都有对应的cid,普通视频就是分p,番剧就是集数, ...
- 每日一个linux命令6 -- rmdir
rmdir doc 如果doc为空目录则删除,否则无法删除. rmdir -p test2/test3 递归删除空目录,首先判断test3,如果test3为空,则删除test3,此时判断test2,如 ...
- git merge了错误分支,如何优雅的回退到merge前的状态?
git merge了错误分支,如何优雅的回退到merge前的状态? 没push的话 git reset --hard (a分支5点那个时候commit之后的sha1) 然后重新 git merge
- 8. 格式化器大一统 -- Spring的Formatter抽象
目录 ✍前言 本文提纲 版本约定 ✍正文 Printer&Parser Formatter 时间日期格式化 Date类型 代码示例 JSR 310类型 整合DateTimeFormatter ...
- 3.k8s存储之ConfigMap、Secret
1.ConfigMap ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件.命令行参数或环境变量中读取配置信息.ConfigMap API 给我们提供了向容器 ...