[SDOI2011]染色 树链剖分
LG传送门
我写这道题的题解主要是因为洛谷上的题解要么讲的不清要么代码丑滑稽,导致初学时的我调了很久,所以想发个题解方便后来人。
由于要维护的信息还是具有区间可加性,只需要记录一下每个区间的左右端点颜色,就可以用树剖+线段树维护。
还不会的同学可以看我的树链剖分总结和线段树总结。
废话不多说直接上代码:看的时候注意一下upd(update)、psu(pushup)、qry(query)、qry0四个函数就好了。
#include<cstdio>
#define R register
#define I inline
using namespace std;
const int S=100003,N=200003,M=400003;
int h[S],s[N],g[N],d[S],t[S],p[S],q[S],r[S],f[S],w[S],u[S],o[M],v[M],a[M],b[M],c,e,n;
I void swp(int &x,int &y){x^=y,y^=x,x^=y;}
I void add(int x,int y){s[++c]=h[x],h[x]=c,g[c]=y;}
I void upd(int k,int z){o[k]=1,v[k]=a[k]=b[k]=z;}
I void psu(int k,int p,int q){
o[k]=o[p]+o[q],a[k]=a[p],b[k]=b[q];
if(b[p]==a[q]) --o[k];
}
I void psd(int k){if(v[k]){R int p=k<<1,q=p|1,z=v[k]; upd(p,z),upd(q,z),v[k]=0;}}
void bld(int k,int l,int r){
if(l==r){o[k]=1,a[k]=b[k]=u[l]; return ;}
R int p=k<<1,q=p|1,m=l+r>>1;
bld(p,l,m),bld(q,m+1,r),psu(k,p,q);
}
void mdf(int k,int l,int r,int x,int y,int z){
if(x<=l&&r<=y){upd(k,z); return ;}
R int p=k<<1,q=p|1,m=l+r>>1; psd(k);
if(x<=m) mdf(p,l,m,x,y,z);
if(y>m) mdf(q,m+1,r,x,y,z);
psu(k,p,q);
}
int qry(int k,int l,int r,int x,int y){
if(x<=l&&r<=y) return o[k];
R int p=k<<1,q=p|1,m=l+r>>1,o=0; psd(k);
if(x<=m) o+=qry(p,l,m,x,y);
if(y>m) o+=qry(q,m+1,r,x,y);
if(x<=m&&y>m) o-=b[p]==a[q];
return o;
}
int col(int k,int l,int r,int x){
if(l==r) return a[k];
R int p=k<<1,q=p|1,m=l+r>>1; psd(k);
if(x<=m) return col(p,l,m,x);
return col(q,m+1,r,x);
}
void dfs1(int x,int f){d[x]=d[f]+1,p[x]=f,t[x]=1;
for(R int i=h[x],y,m=0;i;i=s[i])
if((y=g[i])^f){dfs1(y,x),t[x]+=t[y];
if(t[y]>m) m=t[y],q[x]=y;
}
}
void dfs2(int x,int t){f[x]=++e,u[e]=w[x],r[x]=t;
if(!q[x]) return ; dfs2(q[x],t);
for(R int i=h[x],y;i;i=s[i])
if((y=g[i])^p[x]&&y^q[x]) dfs2(y,y);
}
I void mdf0(int x,int y,int z){
while(r[x]^r[y]){
if(d[r[x]]<d[r[y]]) swp(x,y);
mdf(1,1,n,f[r[x]],f[x],z),x=p[r[x]];
}
if(d[x]>d[y]) swp(x,y);
mdf(1,1,n,f[x],f[y],z);
}
I int qry0(int x,int y){
R int o=0,a=0,b=0;
while(r[x]^r[y]){
if(d[r[x]]<d[r[y]]) swp(x,y),swp(a,b); if(col(1,1,n,f[x])==a) --o;
o+=qry(1,1,n,f[r[x]],f[x]),a=col(1,1,n,f[r[x]]),x=p[r[x]];
}
if(d[x]>d[y]) swp(x,y),swp(a,b);
if(col(1,1,n,f[x])==a) --o; if(col(1,1,n,f[y])==b) --o;
return o+qry(1,1,n,f[x],f[y]);
}
int main(){
freopen("in","r",stdin);
freopen("a.out","w",stdout);
R int m,i,x,y,z; R char o[2];
for(scanf("%d%d",&n,&m),i=1;i<=n;++i) scanf("%d",&w[i]);
for(i=1;i<n;++i) scanf("%d%d",&x,&y),add(x,y),add(y,x);
dfs1(1,0),dfs2(1,1),bld(1,1,n);
for(i=1;i<=m;++i){scanf("%s%d%d",o,&x,&y);
if(o[0]=='C') scanf("%d",&z),mdf0(x,y,z);
else printf("%d\n",qry0(x,y));
}
return 0;
}
[SDOI2011]染色 树链剖分的更多相关文章
- BZOJ 2243: [SDOI2011]染色 [树链剖分]
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6651 Solved: 2432[Submit][Status ...
- bzoj-2243 2243: [SDOI2011]染色(树链剖分)
题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6267 Solved: 2291 Descript ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5020 Solved: 1872[Submit][Status ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
- BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- BZOJ 2243: [SDOI2011]染色 树链剖分+线段树区间合并
2243: [SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数 ...
- 2243: [SDOI2011]染色(树链剖分+线段树)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 8400 Solved: 3150[Submit][Status ...
- Luogu P2486 [SDOI2011]染色(树链剖分+线段树合并)
Luogu P2486 [SDOI2011]染色 题面 题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例: 6 5 2 2 1 2 1 1 1 ...
- [bzoj 2243]: [SDOI2011]染色 [树链剖分][线段树]
Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...
随机推荐
- js oc与线程
分属不同的线程 //定义需要暴露给js的内容,这里我们只暴露personName和queryPersonName接口 @protocol PersonProtocol <JSExport> ...
- 最大传输单元MTU
http://baike.baidu.com/link?url=mU41JFjZzOb3R5crQFCNdocT5ovAswcoIqL2A4U6O5Re_U0-HIYndHG0vSKwc6HbptvH ...
- IE8崩溃在CElement::GetUpdatedLayoutWithContext
发了一个我们页游助手的版本时,测试报告在某些机器上点开某网站时崩溃 "0x637e5067指令引用的0x00000008内存,该内存不能为read",查看dump文件,堆栈如下: ...
- ValueError: Invalid leaf XXX
Bug:ValueError: Invalid leaf XXX 无效的搜索条件——检查search函数中的domain表达式格式!是否少了括号! search(['user_id', '=', us ...
- 了解Session的本质
有一点我们必须承认,大多数web应用程序都离不开session的使用.这篇文章将会结合php以及http协议来分析如何建立一个安全的会话管理机制. AD: 有一点我们必须承认,大多数web应用程序都离 ...
- Spring(六)之自动装配
一.自动装配模型 下面是自动连接模式,可以用来指示Spring容器使用自动连接进行依赖注入.您可以使用元素的autowire属性为bean定义指定autowire模式. 可以使用 byType 或者 ...
- Java 读取properties
package Db; import java.io.InputStream; import java.util.Properties; import java.io.BufferedReader; ...
- 使用appassembler插件生成启动脚本
appassemblermaven插件可以自动生成跨平台的启动脚本,省去了手工写脚本的麻烦,而且还可以生成jsw的后台运行程序.插件官网:http://www.mojohaus.org/appasse ...
- 提交json串格式的POST请求
提交json串格式的POST请求 Action() { web_reg_save_param("retCode", "LB=retCode\":\"& ...
- CC2540 低功耗串口, POWER_SAVING 模式 下 串口 0 的使用
低功耗 模式 下 使用 串口 , 因为 PM2 或者 PM3 状态下 32M晶振 是不工作 的,根据手册得知没有32M晶振, 串口是不能工作的,但是可以使用 外部中断,因此,我把 串口的接收引脚 ...