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)个黑方块的坐标,保证黑方块没有公共边.对于每个黑方块选一个角作为结点,使得所选结点满足输入的一个无向图.其中距离为曼哈顿距离.输出 ...
随机推荐
- [LeetCode]654. Maximum Binary Tree最大堆二叉树
每次找到数组中的最大值,然后递归的构建左右树 public TreeNode constructMaximumBinaryTree(int[] nums) { if (nums.length==0) ...
- 一台PC端安装多店仓信息的删除
如图所示,安装了多店仓,想要删除其中莫一店仓信息! 步骤一:先找到对应目录,一般默认的目录为C:\Users\xxxx\AppData\Roaming\WebPos2.0\bosnatweiniman ...
- 6.裸机C语言控制LED
C语言版LED灯 汇编完成C语言的环境配置 C语言完成点亮LED灯 程序编写 汇编程序start.S .global _start /* 全局标号 */ /* * 描述: _start函数,程序从此函 ...
- 微信小程序--投票小程序设计与实现(图片、视频发布、分组、审核、排名)
投票微信小程序设计与实现(图片.视频发布.分组.审核.排名) 之前接到一个需求,设计一个类似H5 投票系统之类的小程序,我绞尽脑汁,冥思苦想,最后终于做了出来. 再次感谢 @文晓港 的ColorU ...
- 风炫安全web安全学习第三十节课 命令执行&代码执行基础
风炫安全web安全学习第三十节课 命令执行&代码执行基础 代码执行&命令执行 RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统. 远程系统命令执行 ...
- 阿里面试:MySQL如何设计索引更高效?
有情怀,有干货,微信搜索[三太子敖丙]关注这个不一样的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. ...
- Angular入门到精通系列教程(4)- 开发环境搭建以及入手项目
1. 本地开发环境搭建 1.1. node.js 1.2. Angular CLI 2. 开发工具 - Visual Studio Code 第一个Anuglar项目 创建第一个anuglar项目 A ...
- PHP 判断手机端还是web端
function isMobile(){ // 如果有HTTP_X_WAP_PROFILE则一定是移动设备 if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])) re ...
- LeetCode167 两数之和 II - 输入有序数组
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的下标值 ...
- web网上书店总结(jsp+servlet)
web网上书店总结 前端的首页.效果如下: 基本上按照页面有的内容对其实现功能.按照用户划分功能模块,有后台管理员和普通用户,登录的时候会判断账户的类别,例如0权限代表普通用户登录,1权限代表管理员登 ...