【树链剖分】bzoj2243 [SDOI2011]染色
树链剖分模板题。线段树维护每个段中的颜色数、左端点颜色、右端点颜色。
#include<cstdio>
#include<algorithm>
using namespace std;
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define maxn 100001
int col[maxn<<],L[maxn<<],R[maxn<<],delta[maxn<<],n,m,Val[maxn],Num[maxn];
int V[maxn<<],First[maxn<<],Next[maxn<<],All_Lcol,All_Rcol,en;
bool vis[maxn];
int top[maxn],son[maxn],tot,dep[maxn],fa[maxn],siz[maxn],Map[maxn];
inline void AddEdge(const int &UU,const int &VV){V[++en]=VV;Next[en]=First[UU];First[UU]=en;}
inline void pushup(const int &rt)
{
L[rt]=L[rt<<];
R[rt]=R[rt<<|];
col[rt]=col[rt<<]+col[rt<<|]-(R[rt<<]==L[rt<<|]);
}
inline void pushdown(const int &rt)
{
if(delta[rt]!=-)
{
L[rt<<]=R[rt<<]=L[rt<<|]=R[rt<<|]=delta[rt];
delta[rt<<]=delta[rt<<|]=delta[rt];
delta[rt]=-;
col[rt<<]=col[rt<<|]=;
}
}
void buildtree(int rt,int l,int r)
{
delta[rt]=-;
if(l==r)
{
col[rt]=;
L[rt]=R[rt]=Val[Map[l]];//l是线段树中的新位置,
//Map[l]表示新位置对应的在树中的编号是谁
return;
}
int m=l+r>>;
buildtree(lson);
buildtree(rson);
pushup(rt);
}
void update(int ql,int qr,int v,int rt,int l,int r)
{
if(ql<=l&&r<=qr)
{
delta[rt]=L[rt]=R[rt]=v;//更新当前结点的标记值
col[rt]=;
return;
}
pushdown(rt);//将该节点的标记下传到孩子们
int m=l+r>>;
if(ql<=m)
update(ql,qr,v,lson);
if(m<qr)
update(ql,qr,v,rson);
pushup(rt);
}
int query(int ql,int qr,int rt,int l,int r)
{
if(ql==l)
All_Lcol=L[rt];
if(r==qr)
All_Rcol=R[rt];
if(ql<=l&&r<=qr)
return col[rt];
pushdown(rt);//将该节点的标记下传到孩子们
int m=l+r>>,res=,now1=-,now2=-;
if(ql<=m)
{
res+=query(ql,qr,lson);
now1=R[rt<<];
}
if(m<qr)
{
res+=query(ql,qr,rson);
now2=L[rt<<|];
}
res-=(now1==now2 && now1!=-);
return res;
}
inline void Update(int u,int v,int val)
{
int f1=top[u],f2=top[v];
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(u,v);
swap(f1,f2);
}
update(Num[f1],Num[u],val,,,n);
u=fa[f1];
f1=top[u];
}
if(dep[u]<dep[v])
swap(u,v);
update(Num[v],Num[u],val,,,n);
}
inline int Query(int u,int v)
{
int f1=top[u],f2=top[v],ans=,t1=-,t2=-;
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(u,v);
swap(f1,f2);
swap(t1,t2);
}
ans+=query(Num[f1],Num[u],,,n);
ans-=(t1==All_Rcol);
t1=All_Lcol;
u=fa[f1];
f1=top[u];
}
if(dep[u]<dep[v])
{
swap(u,v);
swap(t1,t2);
}
ans+=query(Num[v],Num[u],,,n);
ans-=((t1==All_Rcol&&t1!=-)+(t2==All_Lcol&&t2!=-));
return ans;
}
void dfs1(int cur,int father,int depth)
{
fa[cur]=father;
dep[cur]=depth;
siz[cur]=;
for(int i=First[cur];i;i=Next[i])
if(!vis[V[i]])
{
vis[V[i]]=true;
dfs1(V[i],cur,depth+);
siz[cur]+=siz[V[i]];
if(siz[V[i]]>siz[son[cur]])
son[cur]=V[i];
vis[V[i]]=false;
}
}
void dfs2(int cur)
{
if(son[cur]&&!vis[son[cur]])
{
vis[son[cur]]=true;
top[son[cur]]=top[cur];
Num[son[cur]]=++tot;
Map[tot]=son[cur];
dfs2(son[cur]);
vis[son[cur]]=false;
}
for(int i=First[cur];i;i=Next[i])
if(son[cur]!=V[i]&&!vis[V[i]])
{
vis[V[i]]=true;
top[V[i]]=V[i];
Num[V[i]]=++tot;
Map[tot]=V[i];
dfs2(V[i]);
vis[V[i]]=false;
}
}
int Res,num;
char C;
char CH[];
inline int getint()
{
Res=;
C='*';
while(C<''||C>'')
C=getchar();
while(C>=''&&C<='')
{
Res=Res*+(C-'');
C=getchar();
}
return Res;
}
inline void putint(int x)
{
num=;
while(x>)
CH[++num]=x%,x/=;
while(num)
putchar(CH[num--]+);
putchar('\n');
}
int main()
{
int x,y,a,b,c;
char op;
n=getint();
m=getint();
for(int i=;i<=n;i++)
Val[i]=getint();
for(int i=;i<n;i++){x=getint();y=getint();AddEdge(x,y);AddEdge(y,x);}
top[]=;
Num[]=++tot;
Map[tot]=;
vis[]=true;
dfs1(,,);
dfs2();
buildtree(,,n);
for(int i=;i<=m;i++)
{
getchar();
op=getchar();
a=getint();
b=getint();
if(op=='C')
{
c=getint();
Update(a,b,c);
}
else
putint(Query(a,b));
}
return ;
}
【树链剖分】bzoj2243 [SDOI2011]染色的更多相关文章
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- bzoj-2243 2243: [SDOI2011]染色(树链剖分)
题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6267 Solved: 2291 Descript ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
- BZOJ2243 洛谷2486 [SDOI2011]染色 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...
- BZOJ2243 SDOI2011 染色 【树链剖分】
BZOJ2243 SDOI2011 染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色 ...
- [BZOJ2243][SDOI2011]染色 解题报告|树链剖分
Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...
- BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)
题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...
- BZOJ2243: [SDOI2011]染色(树链剖分/LCT)
Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如 ...
- 【BZOJ2243】【SDOI2011】染色(树链剖分,线段树)
题面 我们也要换个花样,这回提供洛谷的题面 题解 线段树+树链剖分大水题 维护颜色段的方法很简单呀... 维护当前区间内的颜色段个数, 以及当前区间左端和右端的颜色, 合并的时候考虑是否要减一下就行了 ...
随机推荐
- 玩一下易语言 "和"字有多种读音,注定了它的重要性!!
变量名 类型 静态 数组 备注 拼音 文本型 0 测试的汉字 文本型 有几种发音 整数型 i 整数型 测试用的汉字 = “和” 有几种发音 = 取发音数目 ...
- Android--hardwareAccelerated 硬件加速详解 android:largeHeap="true"
做项目时,引导页面的ViewPager报了OOM异常,图片并不大,在清单文件Application节点中添加了两行代码就解决了这个问题 android:hardwareAccelerated=&quo ...
- perl6中的hash定义(1)
,,,); say %hash; , b => ); say %hash2; my %hash3 = (:name('root'), :host('localost')); say %hash3 ...
- thread线程栈size及局部变量最大可分配size【转】
转自:http://blog.csdn.net/sunny04/article/details/46805261 版权声明:本文为博主原创文章,未经博主允许不得转载. 进程是操作系统的最小资源管理单元 ...
- python实战===2017年30个惊艳的Python开源项目 (转)
本文转自:http://www.sohu.com/a/216723120_115128 摘要:本文来自Mybridge,介绍了过去一年里30个惊艳的Python开源项目.点击每一个都可以在GitHub ...
- 64_g3
gimp-resynthesizer-2.0-6.20160601git787ee5a.fc2..> 11-Feb-2017 05:36 77650 gimp-save-for-web-0.29 ...
- C基础 读写锁中级剖析
引言 读写锁 是为了 解决, 大量 ''读'' 和 少量 ''写'' 的业务而设计的. 读写锁有3个特征: 1.当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞 2.当 ...
- python 几种循环性能测试: while, for, 列表生成式, map等
直接上代码: #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/07/24 16:23 import itertools imp ...
- AC日记——【模板】Link Cut Tree 洛谷 P3690
[模板]Link Cut Tree 思路: LCT模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 30 ...
- SPOJ - SUBST1 D - New Distinct Substrings
D - New Distinct Substrings 题目大意:求一个字符串中不同子串的个数. 裸的后缀数组 #include<bits/stdc++.h> #define LL lon ...