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]染色 树链剖分的更多相关文章

  1. BZOJ 2243: [SDOI2011]染色 [树链剖分]

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6651  Solved: 2432[Submit][Status ...

  2. bzoj-2243 2243: [SDOI2011]染色(树链剖分)

    题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6267  Solved: 2291 Descript ...

  3. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  4. Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5020  Solved: 1872[Submit][Status ...

  5. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

  6. BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  7. BZOJ 2243: [SDOI2011]染色 树链剖分+线段树区间合并

    2243: [SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数 ...

  8. 2243: [SDOI2011]染色(树链剖分+线段树)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 8400  Solved: 3150[Submit][Status ...

  9. Luogu P2486 [SDOI2011]染色(树链剖分+线段树合并)

    Luogu P2486 [SDOI2011]染色 题面 题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例: 6 5 2 2 1 2 1 1 1 ...

  10. [bzoj 2243]: [SDOI2011]染色 [树链剖分][线段树]

    Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...

随机推荐

  1. P3177 [HAOI2015]树上染色

    题目描述 有一棵点数为 N 的树,树边有边权.给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 . 将所有点染色后,你会获得黑点两两之 ...

  2. [19/04/25-星期四] GOF23_结构型模式(适配器模式、代理模式)

    一.引言 结构模式:核心作用就是从程序的结构上实现松耦合,从而扩大整体的类结构,用来解决更大的问题. 二.适配器模式(adapter) 生活中假设笔记本是标准的USB接口但是外置键盘是圆形接口,这时候 ...

  3. Java50道经典习题-程序21 求阶乘

    题目:求1+2!+3!+...+20!的和分析:使用递归求解 0的阶乘和1的阶乘都为1 public class Prog21{ public static void main(String[] ar ...

  4. MAX7456和DP7456的对比

    DP7456 是一款集成了 EEPROM 的单通道.单色随屏显示发生器,集成了视频驱动器.同步分离器.视频分离开关以及 EEPROM,提高了系统的集成度,有效降低了系统成本. DP7456 采用符合  ...

  5. Android的JNI调用(二)

    Android Studio 2.3在native下已经有了代码提示功能,按照提示下载相应组件就可以debug native代码. 一.Java调用JNI与JNI调用Java 1.1 C调用Java ...

  6. DPDK中使用VFIO的配置

    VFIO VFIO是一个可以安全地把设备I/O.中断.DMA等暴露到用户空间(userspace),从而可以在用户空间完成设备驱动的框架.用户空间直接设备访问,虚拟机设备分配可以获得更高的IO性能. ...

  7. cocos2d-x 音效中断问题

    做跑酷重吃金币播音效时,播放其它音效会使得音效所有中断,最后发现时音效上限的问题,2.2.3默认的似乎是5个音效,改动成50后问题解决. 在java中的org.cocos2dx.lib包下有一个Coc ...

  8. git did not exit cleanly (exit code 1)

    git pull的时候报如下错误: error: Your local changes to the following files would be overwritten by merge: 文件 ...

  9. java环境变量配置(win7)

    JDK1.8 1.单击“计算机-属性-高级系统设置”,单击“环境变量”.在“系统变量”栏下单击“新建”,创建新的系统环境变量. 2.  (1)新建->变量名"JAVA_HOME&quo ...

  10. 01迷宫题解(bfs,联通块)

    题目https://www.luogu.org/problemnew/show/P1141 这个题解主要针对我个人出现的一些问题和注意的地方. 解题思路 首先说一下联通块 联通块这个比较抽象,举个例子 ...