[SDOI2011]染色(luogu)

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)路径上的颜色段数量。
ouput
对于每个询问操作,输出一行答案。
Solution
树链剖分处理色块(注意相邻两段的首尾颜色相同的情况)
主要是细节,详见代码
Code

#include <cstdio>
#include <cstdlib>
#include <vector>
using namespace std;
const int N=1e5+;
struct node
{
int l,r,lc,rc,cl,cr,sum;
bool flag;
}f[N*];
int fa[N],deep[N],son[N],d[N],dfn[N],si[N],top[N],rt,
tot,cnt,n,m,u,v,c,re[N],L,R,a,b;
char s[];
vector <int> link[N];
void dfs1(int u,int f)
{
fa[u]=f;
deep[u]=deep[f]+;
si[u]=;
int size=link[u].size();
for(int i=;i<size;i++)
{
int v=link[u][i];
if(v!=f)
{
dfs1(v,u);
si[u]+=si[v];
if(son[u]== || si[son[u]]<si[v]) son[u]=v;
}
}
}
void dfs2(int u,int f)
{
dfn[u]=++cnt,re[cnt]=u;
if(son[u]!=) top[son[u]]=top[u],dfs2(son[u],u);
int size=link[u].size();
for(int i=;i<size;i++)
{
int v=link[u][i];
if(v!=f && v!=son[u])
top[v]=v,dfs2(v,u);
}
}
void push_up(int g)
{
int lc=f[g].lc,rc=f[g].rc;
f[g].cl=f[lc].cl,f[g].cr=f[rc].cr;
f[g].sum=f[lc].sum+f[rc].sum;
if(f[lc].cr==f[rc].cl) f[g].sum--;
}
void push_down(int g)
{
if(f[g].flag)
{
int lc=f[g].lc,rc=f[g].rc;
f[lc].flag=f[rc].flag=true;
f[lc].cl=f[lc].cr=f[rc].cl=f[rc].cr=f[g].cl;
f[lc].sum=f[rc].sum=;
f[g].flag=false;
}
}
void build(int &g,int l,int r)
{
g=++tot;
f[g].l=l,f[g].r=r;
if(l==r)
{
f[g].flag=true,f[g].sum=;
f[g].cl=f[g].cr=d[re[l]];
return ;
}
int mid=(l+r)>>;
build(f[g].lc,l,mid);
build(f[g].rc,mid+,r);
push_up(g);
}
void add(int g,int l,int r,int c)
{
if(f[g].l>=l && f[g].r<=r)
f[g].flag=true,f[g].cl=f[g].cr=c,f[g].sum=;
else
{
push_down(g);
int mid=(f[g].l+f[g].r)>>;
if(r<=mid) add(f[g].lc,l,r,c);
else if(l>mid) add(f[g].rc,l,r,c);
else add(f[g].lc,l,mid,c),add(f[g].rc,mid+,r,c);
push_up(g);
}
}
void Add(int x,int y,int c)
{
int px=top[x],py=top[y];
while(px!=py)
if(deep[px]>deep[py])
add(rt,dfn[px],dfn[x],c),x=fa[px],px=top[x];
else add(rt,dfn[py],dfn[y],c),y=fa[py],py=top[y];
if(dfn[x]<dfn[y]) add(rt,dfn[x],dfn[y],c);
else add(rt,dfn[y],dfn[x],c);
}
int get(int g,int l,int r)
{
if(f[g].l==L) a=f[g].cl;
if(f[g].r==R) b=f[g].cr;
if(f[g].l>=l && f[g].r<=r)
return f[g].sum;
else
{
push_down(g);
int mid=(f[g].l+f[g].r)>>;
if(r<=mid) return get(f[g].lc,l,r);
else if(l>mid) return get(f[g].rc,l,r);
else
{
int ans=get(f[g].lc,l,mid)+get(f[g].rc,mid+,r);
if(f[f[g].lc].cr==f[f[g].rc].cl) ans--;
return ans;
}
}
}
int Get(int x,int y)
{
int ans=;
int px=top[x],py=top[y];
int l_x=-,l_y=-;
while(px!=py)
if(deep[px]>deep[py])
{
L=dfn[px],R=dfn[x];
ans+=get(rt,dfn[px],dfn[x]);
x=fa[px],px=top[x];
if(b==l_x) ans--;
l_x=a;
}
else
{
L=dfn[py],R=dfn[y];
ans+=get(rt,dfn[py],dfn[y]);
y=fa[py],py=top[y];
if(b==l_y) ans--;
l_y=a;
}
if(dfn[x]>dfn[y]) swap(x,y),swap(l_x,l_y);
L=dfn[x],R=dfn[y];
ans+=get(rt,dfn[x],dfn[y]);
if(a==l_x) ans--;
if(b==l_y) ans--;
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&d[i]);
for(int i=;i<n;i++)
{
scanf("%d%d",&u,&v);
link[u].push_back(v);
link[v].push_back(u);
}
dfs1(,);
top[]=,dfs2(,);
build(rt,,cnt);
while(m--)
{
scanf("%s%d%d",s,&u,&v);
if(s[]=='C')
{
scanf("%d",&c);
Add(u,v,c);
}
else if(s[]=='Q')
printf("%d\n",Get(u,v));
}
return ;
}

[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. ES基本语法

    7.2.0版本 1 创建库 http://{ip}:{port}/{库名称} put 2 查询库 http://{ip}:{port}/_cat/indices?v get health status ...

  2. Java 学习笔记(11)——lambda 表达式

    在写Java代码的时候,如果某个地方需要一个接口的实现类,一般的做法是新定义一个实现类,并重写接口中的方法,在需要使用的时候new一个实现类对象使用,为了一个简单的接口或者说为了一个回调函数就得额外编 ...

  3. easypermissions拒绝权限后闪退。 java.lang.NoSuchMethodError: No virtual method isStateSaved()Z in class Landroid/support/v4/app/FragmentManager

    Process: com.tazan.cd.streetlight, PID: 18825 java.lang.NoSuchMethodError: No virtual method isState ...

  4. python OrderedDict

    15年16年接触python时候,还不知道这个函数,只知道dict的无序,造成了一些麻烦 今天view 代码,发现了 OrderedDict() 在python2.7中比较吃内存 pop(获取指定ke ...

  5. 最全最详细的PHP面试题(带有答案)

    这篇文章介绍的内容是关于最全最详细的PHP面试题(带有答案),有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 相关推荐: 分享一波腾讯PHP面试题 2019年PHP最新面试题(含答案) ...

  6. Java操作Jxl实现导出数据生成Excel表格数据文件

    实现:前台用的框架是Easyui+Bootstrap结合使用,需要引入相应的Js.Css文件.页面:Jsp.拦截请求:Servlet.逻辑处理:ClassBean.数据库:SQLserver. 注意: ...

  7. 【转载】CSS flex属性深入理解

    文章转载自 张鑫旭-鑫空间-鑫生活 http://www.zhangxinxu.com/ 原文链接:https://www.zhangxinxu.com/wordpress/2019/12/css-f ...

  8. 09_$.ajax()参数详解及标准写法

    1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如 ...

  9. Java 多线程与并发(六):AQS

    我们前面几张提到过,JUC 这个包里面的工具类的底层就是使用 CAS 和 volatile 来保证线程安全的,整个 JUC 包里面的类都是基于它们构建的.今天我们介绍一个非常重要的同步器,这个类是 J ...

  10. JVM之GC(一)

    Java较C而言,最大的区别在于内存管理.JVM设有无用内存空间自动回收复用机制,也就是我们所说的GC. 之前说过,栈是为线程.为函数的执行分配内存的地方,用完即“销毁”,这里留待以后做深入探讨:堆是 ...