BZOJ2243: [SDOI2011]染色(树链剖分/LCT)
Description
Input
Output
对于每个询问操作,输出一行答案。
Sample Input
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
Sample Output
1
2
解题思路:
1.树链剖分:
只修改链,不修改关系,树链剖分。
线段树维护树链剖分序。
时间复杂度O(nlogn2)
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lll spc<<1
#define rrr spc<<1|1
using std::min;
using std::max;
using std::swap;
struct trnt{
int lc;
int rc;
int lzt;
int val;
}tr[];
struct pnt{
int hd;
int col;
int mxs;
int ind;
int fa;
int tp;
int wgt;
int dp;
}p[];
struct ent{
int twd;
int lst;
}e[];
struct bag{
int cl;
int cr;
int vl;
bag friend operator + (bag a,bag b)
{
if(!a.cl)
a.cl=b.cl;
if(!b.cr)
b.cr=a.cr;
return (bag){a.cl,b.cr,(a.vl+b.vl-(a.cr==b.cl)<)?:(a.vl+b.vl-(a.cr==b.cl))};
}
};
int n,m;
int cnt;
int dfn;
char cmd[];
void ade(int f,int t)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
return ;
}
void pushup(int spc)
{
tr[spc].lc=tr[lll].lc;
tr[spc].rc=tr[rrr].rc;
tr[spc].val=tr[lll].val+tr[rrr].val-(tr[lll].rc==tr[rrr].lc);
return ;
}
void chg(int spc,int v)
{
tr[spc].val=;
tr[spc].lc=tr[spc].rc=v;
tr[spc].lzt=v;
return ;
}
void pushdown(int spc)
{
if(tr[spc].lzt)
{
chg(lll,tr[spc].lzt);
chg(rrr,tr[spc].lzt);
tr[spc].lzt=;
}
return ;
}
void build(int l,int r,int pos,int spc,int v)
{
if(l==r)
{
tr[spc].lc=tr[spc].rc=v;
tr[spc].val=;
tr[spc].lzt=;
return ;
}
int mid=(l+r)>>;
if(pos<=mid)
build(l,mid,pos,lll,v);
else
build(mid+,r,pos,rrr,v);
pushup(spc);
return ;
}
void Basic_dfs(int x,int f)
{
p[x].dp=p[f].dp+;
p[x].fa=f;
int maxs=-;
p[x].wgt=;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f)
continue;
Basic_dfs(to,x);
p[x].wgt+=p[to].wgt;
if(p[to].wgt>maxs)
{
maxs=p[to].wgt;
p[x].mxs=to;
}
}
return ;
}
void Build_dfs(int x,int tpl)
{
if(!x)
return ;
p[x].tp=tpl;
p[x].ind=++dfn;
build(,n,dfn,,p[x].col);
Build_dfs(p[x].mxs,tpl);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].ind)
continue;
Build_dfs(to,to);
}
}
void update(int l,int r,int ll,int rr,int spc,int v)
{
if(ll>rr)
return ;
if(l>rr||ll>r)
return ;
pushdown(spc);
if(ll<=l&&r<=rr)
{
chg(spc,v);
return ;
}
int mid=(l+r)>>;
update(l,mid,ll,rr,lll,v);
update(mid+,r,ll,rr,rrr,v);
pushup(spc);
return ;
}
bag mk(int a,int b,int c)
{
return (bag){a,b,c};
}
bag ask(int l,int r,int ll,int rr,int spc)
{
if(l>rr||ll>r)
return mk(,,);
pushdown(spc);
if(ll<=l&&r<=rr)
return mk(tr[spc].lc,tr[spc].rc,tr[spc].val);
int mid=(l+r)>>;
return ask(l,mid,ll,rr,lll)+ask(mid+,r,ll,rr,rrr);
}
int lca(int x,int y)
{
while(p[x].tp!=p[y].tp)
{
if(p[p[x].tp].dp<p[p[y].tp].dp)
swap(x,y);
x=p[p[x].tp].fa;
}
if(p[x].dp>p[y].dp)
swap(x,y);
return x;
}
void rvs(bag &a)
{
swap(a.cl,a.cr);
return ;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&p[i].col);
for(int i=;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
ade(a,b);
ade(b,a);
}
Basic_dfs(,);
Build_dfs(,);
while(m--)
{
scanf("%s",cmd);
if(cmd[]=='C')
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
int f=lca(a,b);
while(p[a].tp!=p[f].tp)
{
update(,dfn,p[p[a].tp].ind,p[a].ind,,c);
a=p[p[a].tp].fa;
}
update(,dfn,p[f].ind,p[a].ind,,c);
a=b;
while(p[a].tp!=p[f].tp)
{
update(,dfn,p[p[a].tp].ind,p[a].ind,,c);
a=p[p[a].tp].fa;
}
update(,dfn,p[f].ind,p[a].ind,,c);
}
if(cmd[]=='Q')
{
int a,b; scanf("%d%d",&a,&b);
int f=lca(a,b);
bag ans=(bag){,,};
while(p[a].tp!=p[f].tp)
{
ans=ask(,dfn,p[p[a].tp].ind,p[a].ind,)+ans;
a=p[p[a].tp].fa;
}
if(a!=f)
ans=ask(,dfn,p[f].ind+,p[a].ind,)+ans;
bag ams=(bag){,,};
a=b;
while(p[a].tp!=p[f].tp)
{
ams=ask(,dfn,p[p[a].tp].ind,p[a].ind,)+ams;
a=p[p[a].tp].fa;
}
if(a!=f)
ams=ask(,dfn,p[f].ind+,p[a].ind,)+ams;
ans=ask(,dfn,p[f].ind,p[f].ind,)+ans;
rvs(ans);
ans=ans+ams;
printf("%d\n",ans.vl);
}
}
return ;
}
2.LCT:
比较板子了。
每次维护左侧颜色和右侧颜色(注意特判0节点值)
反转时要反转左右颜色。
路径提取一下输出答案就好了。
时间复杂度O(nlogn)理论上比树剖快
但是:
蒟蒻的我:splay常数居然比logn大

代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lll tr[spc].ch[0]
#define rrr tr[spc].ch[1]
#define ls ch[0]
#define rs ch[1]
using std::swap;
struct trnt{
int ch[];
int fa;
int lzt;
int chg;
int sum;
int val;
int lc;
int rc;
int wgt;
bool anc;
}tr[];
int n,m;
char cmd[];
bool whc(int spc)
{
return tr[tr[spc].fa].rs==spc;
}
void pushup(int spc)
{
tr[spc].wgt=tr[lll].wgt+tr[rrr].wgt+;
tr[spc].sum=tr[lll].sum+tr[rrr].sum+-(tr[lll].rc==tr[spc].val)-(tr[rrr].lc==tr[spc].val);
tr[spc].lc=tr[lll].lc?tr[lll].lc:tr[spc].val;
tr[spc].rc=tr[rrr].rc?tr[rrr].rc:tr[spc].val;
return ;
}
void trr(int spc)
{
if(!spc)
return ;
swap(lll,rrr);
swap(tr[spc].lc,tr[spc].rc);
tr[spc].lzt^=;
return ;
}
void upd(int spc,int v)
{
if(!spc)
return ;
tr[spc].val=tr[spc].lc=tr[spc].rc=v;
tr[spc].sum=;
tr[spc].chg=v;
return ;
}
void pushdown(int spc)
{
if(tr[spc].lzt)
{
trr(lll);
trr(rrr);
tr[spc].lzt=;
}
if(tr[spc].chg)
{
upd(lll,tr[spc].chg);
upd(rrr,tr[spc].chg);
tr[spc].chg=;
}
return ;
}
void recal(int spc)
{
if(!tr[spc].anc)
recal(tr[spc].fa);
pushdown(spc);
return ;
}
void rotate(int spc)
{
int f=tr[spc].fa;
bool k=whc(spc);
tr[f].ch[k]=tr[spc].ch[!k];
tr[spc].ch[!k]=f;
if(tr[f].anc)
{
tr[spc].anc=;
tr[f].anc=;
}else
tr[tr[f].fa].ch[whc(f)]=spc;
tr[spc].fa=tr[f].fa;
tr[f].fa=spc;
tr[tr[f].ch[k]].fa=f;
pushup(f);
pushup(spc);
return ;
}
void splay(int spc)
{
recal(spc);
while(!tr[spc].anc)
{
int f=tr[spc].fa;
if(tr[f].anc)
{
rotate(spc);
return ;
}
if(whc(spc)^whc(f))
rotate(spc);
else
rotate(f);
rotate(spc);
}
return ;
}
void access(int spc)
{
int lst=;
while(spc)
{
splay(spc);
tr[rrr].anc=;
tr[lst].anc=;
rrr=lst;
pushup(spc);
lst=spc;
spc=tr[spc].fa;
}
return ;
}
void Mtr(int spc)
{
access(spc);
splay(spc);
trr(spc);
return ;
}
void split(int x,int y)
{
Mtr(x);
access(y);
splay(y);
return ;
}
void link(int x,int y)
{
Mtr(x);
tr[x].fa=y;
return;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
tr[i].anc=;
scanf("%d",&tr[i].val);
tr[i].lc=tr[i].rc=tr[i].val;
}
for(int i=;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
link(a,b);
}
while(m--)
{
scanf("%s",cmd);
if(cmd[]=='Q')
{
int a,b;
scanf("%d%d",&a,&b);
split(a,b);
printf("%d\n",tr[b].sum);
}else{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
split(a,b);
upd(b,c);
}
}
return ;
}
BZOJ2243: [SDOI2011]染色(树链剖分/LCT)的更多相关文章
- 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 ...
- BZOJ2243[SDOI2011]染色——树链剖分+线段树
题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221 ...
- 【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 洛谷2486 [SDOI2011]染色 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...
- BZOJ 2243: [SDOI2011]染色 [树链剖分]
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6651 Solved: 2432[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 ...
随机推荐
- CheckBox:屏蔽setChecked方法对OnCheckedChangeListener的影响
对于CheckBox的OnCheckedChangeListener,有两种情况下会被触发: (1)用户点击了一下CheckBox: (2)代码中调用了setChecked(boolean check ...
- SharePoint创建Alternate Access Mapping (AAM)备用訪问映射
SharePoint创建Alternate Access Mapping (AAM)备用訪问映射 SharePoint的仓库是SQL Server中的内容数据库.这些数据库储存着组织全 ...
- 之前写的收集的一些c++代码片,算法排序,读文件,写日志,快速求积分等等
写日志: class LogFile { public: static LogFile &instance(); operator FILE *() const { return m_file ...
- 版本控制Git(1)——理解暂存区
一.svn和Git的比较 我们都知道传统的源代码管理都是以服务器为中心的,每个开发者都直接连在中间服务器上, 本地修改,然后commit到svn服务器上.这种做法看似完美,但是有致命的缺陷. 1. 开 ...
- SQL Server 2005高可用性模式下创建数据库镜像
SQL Server 2005高可用性模式下创建数据库镜像 高可用性模式下创建数据库镜像 第一步: --创建镜像用数据库-在主服务器上操作 create database db_mirror on ...
- javaScript 原型与原型链学习笔记
javaScript中,原型是常用到一种方式,它能降低储存占用,写出更高效的代码 原型常用到的则是prototype属性 JavaScript prototype 属性 定义和用法 prototype ...
- mysql not in用法
select * from zan where uid not in(select uid from zan where zhongjiang !=0) group by uid order by r ...
- @Mapper 和 @MapperScan 区别
1.@Mapper : 为了使接口被其他类引用,需要使用@Mapper注解,这种方式要求每一个mapper类都需要添加此注解,麻烦. package com.example.demo.dao; imp ...
- FZU 1096 QS Network
QS Network Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on FZU. Original ID: ...
- CSUOJ 1541 There is No Alternative
There is No Alternative Time Limit: 3000ms Memory Limit: 262144KB This problem will be judged on Aiz ...