[SDOI2011]染色(树链剖分)
Description
#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]染色(树链剖分)的更多相关文章
- 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路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...
随机推荐
- (1)51单片机NOP指令
提问:什么是NOP指令?干什么用的?单片机程序里执行一条nop指令需要多长时间? (1)一个NOP就是一个机器周期 (2)空指令,延时一个机器周期 (3)这个与单片机型号.指令类型和使用的晶振频率有关 ...
- POJ 2976 Dropping tests [二分]
1.题意:同poj3111,给出一组N个有价值a,重量b的物品,问去除K个之后,剩下的物品的平均值最大能取到多少? 2.分析:二分平均值,注意是去除K个,也就是选取N-K个 3.代码: # inclu ...
- 关于C#异步编程你应该了解的几点建议
前段时间写了一篇关于C#异步编程入门的文章,你可以点击<C#异步编程入门看这篇就够了>查看.这篇文章我们来讨论下关于C#异步编程几个不成文的建议,希望对你写出高性能的异步编程代码有所帮助. ...
- Python3 批量修改JPG图片尺寸
功能 批量修改当前文件夹下的jpg图片到设置的尺寸 将修改后的图片移动到 new_img 这个文件夹下 导入库 from PIL import Image # 处理图片模块 import os imp ...
- mysql主从之多元复制
实验环境: 192.168.132.121 master1 192.168.132.122 master2 192.168.132.123 slave 使用gtid的方式 两个主分别是19 ...
- 从零开始のcocos2dx生活(四)ActionManager
文章目录 初始化构造函数 析构函数 删除哈希元素 分配存放动作对象的空间 通过索引移除动作 暂停动作 恢复动作 暂停所有的动作 恢复所有的动作 添加动作 移除所有的动作 移除target中的所有动作 ...
- 【题解】HDU Homework(倍增)
[题解]HDU Homework(倍增) 矩阵题一定要多多检查一下是否行列反了... 一百个递推项一定要存101个 说多了都是泪啊 一下午就做了这一道题因为实在是太菜了太久没写这种矩阵的题目... 设 ...
- 【题解】BZOJ5093图的价值(二项式+NTT)
[题解]BZOJ5093图的价值(二项式+NTT) 今天才做这道题,是我太弱了 强烈吐槽c++这种垃圾语言tmd数组越界不re反倒去别的数组里搞事情我只想说QAQ 推了一张A4纸的式子 考虑每个点的度 ...
- Codeforces Round #612 (Div. 2)
https://codeforces.com/contest/1287/ A - Angry Students 题意:求A后面的P最长连续有几个? 题解:? int n; char s[200005] ...
- Serverless Kubernetes 入门:对 Kubernetes 做减法
作者 | 贤维 阿里巴巴高级技术专家 导读:Serverless Kubernetes 是阿里云容器服务团队对未来 Kubernetes 演进方向的一种探索,通过对 Kubernetes 做减法,降 ...