给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),
如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作=。
题解:树链剖分+线段树,线段树维护区间左右的颜色和种类数,合并就很简单了,考虑左区间的右端点和右区间的左端点是不是一样颜色,然后树上暴跳的时候要比较深度来跳了,然后修改也是在树上暴跳即可

/**************************************************************
Problem: 2243
User: walfy
Language: C++
Result: Accepted
Time:5192 ms
Memory:48268 kb
****************************************************************/ //#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; struct edge{
int to,Next;
}e[maxn];
int cnt,head[N];
int son[N],fa[N],top[N],sz[N],id[N];
int res,w[N],re[N],dep[N];
void add(int u,int v)
{
e[cnt].to=v;
e[cnt].Next=head[u];
head[u]=cnt++;
}
void init()
{
cnt=;
memset(head,-,sizeof head);
memset(son,-,sizeof son);
}
void dfs1(int u,int f,int de)
{
fa[u]=f;sz[u]=;
dep[u]=de;
for(int i=head[u];~i;i=e[i].Next)
{
int v=e[i].to;
if(v!=f)
{
dfs1(v,u,de+);
sz[u]+=sz[v];
if(son[u]==-||sz[v]>sz[son[u]])son[u]=v;
}
}
}
void dfs2(int u,int f,int tp)
{
top[u]=tp;
id[u]=++res;
if(son[u]!=-)dfs2(son[u],u,tp);
for(int i=head[u];~i;i=e[i].Next)
{
int v=e[i].to;
if(v!=f&&v!=son[u])dfs2(v,u,v);
}
}
struct node{
int cl,cr,co;
}sum[N<<];
node gao(node a,node b)
{
if(a.cl==-)a=b;
else if(b.cl==-);
else
{
a.co+=b.co;
if(a.cr==b.cl)a.co--;
a.cr=b.cr;
}
return a;
}
int lazy[N<<];
void pushdown(int rt)
{
if(lazy[rt]!=-)
{
sum[rt<<].co=sum[rt<<|].co=;
sum[rt<<].cl=sum[rt<<|].cl=lazy[rt];
sum[rt<<].cr=sum[rt<<|].cr=lazy[rt];
lazy[rt<<]=lazy[rt<<|]=lazy[rt];
lazy[rt]=-;
}
}
void pushup(int rt)
{
sum[rt]=gao(sum[rt<<],sum[rt<<|]);
}
void build(int l,int r,int rt)
{
lazy[rt]=-;
if(l==r){sum[rt].cl=sum[rt].cr=w[re[l]];sum[rt].co=;return ;}
int m=(l+r)>>;
build(ls);build(rs);
pushup(rt);
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
sum[rt].co=,sum[rt].cl=sum[rt].cr=c;
lazy[rt]=c;
return ;
}
pushdown(rt);
int m=(l+r)>>;
if(L<=m)update(L,R,c,ls);
if(m<R)update(L,R,c,rs);
pushup(rt);
}
node query1(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)return sum[rt];
pushdown(rt);
int m=(l+r)>>;
node ans{-,-,};
if(L<=m)ans=gao(ans,query1(L,R,ls));
if(m<R)ans=gao(ans,query1(L,R,rs));
return ans;
}
int query(int a,int b)
{
int f1=top[a],f2=top[b],ans=;
node aa{-,-,},bb{-,-,};
while(f1!=f2)
{
if(dep[f1]>dep[f2])
{
node te=query1(id[f1],id[a],,res,);
swap(te.cl,te.cr);
aa=gao(aa,te);
a=fa[f1];f1=top[a];
}
else
{
node te=query1(id[f2],id[b],,res,);
swap(te.cl,te.cr);
bb=gao(bb,te);
b=fa[f2];f2=top[b];
}
}
if(dep[a]<dep[b])
{
node te=query1(id[a],id[b],,res,);
aa=gao(aa,te);
swap(bb.cl,bb.cr);
aa=gao(aa,bb);
}
else
{
node te=query1(id[b],id[a],,res,);
swap(te.cl,te.cr);
aa=gao(aa,te);
swap(bb.cl,bb.cr);
aa=gao(aa,bb);
}
return aa.co;
}
void change(int a,int b,int c)
{
int f1=top[a],f2=top[b];
while(f1!=f2)
{
if(dep[f1]<dep[f2])swap(f1,f2),swap(a,b);
update(id[f1],id[a],c,,res,);
a=fa[f1],f1=top[a];
}
if(dep[a]>dep[b])swap(a,b);
// printf("%d %d %d %d\n",id[a],id[b],a,b);
update(id[a],id[b],c,,res,);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&w[i]);
init();
for(int i=;i<n;i++)
{
int a,b;scanf("%d%d",&a,&b);
add(a,b);add(b,a);
}
dfs1(,-,);
dfs2(,-,);
for(int i=;i<=res;i++)re[id[i]]=i;
build(,res,);
while(m--)
{
char op[];
scanf("%s",op);
if(op[]=='C')
{
int a,b,c;scanf("%d%d%d",&a,&b,&c);
change(a,b,c);
}
else
{
int a,b;scanf("%d%d",&a,&b);
printf("%d\n",query(a,b));
}
}
return ;
}
/***********************
8 100
3 2 2 2 4 1 1 3
1 3
1 5
1 7
3 6
3 4
5 2
2 8
***********************/

2243: [SDOI2011]染色 树链剖分+线段树染色的更多相关文章

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

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

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

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

  3. B20J_2243_[SDOI2011]染色_树链剖分+线段树

    B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...

  4. BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)

    题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...

  5. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  6. 【bzoj1959】[Ahoi2005]LANE 航线规划 树链剖分+线段树

    题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...

  7. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  8. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  9. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

随机推荐

  1. Fundamental theorem of arithmetic 为什么1不是质数

    https://en.wikipedia.org/wiki/Fundamental_theorem_of_arithmetic In number theory, the fundamental th ...

  2. Python开发【Tornado】:简介与使用

    Tornado框架 简介: Tornado是使用Python编写的一个强大的.可扩展的Web服务器.它在处理严峻的网络流量时表现得足够强健,但却在创建和编写时有着足够的轻量级,并能够被用在大量的应用和 ...

  3. Android中的Handler及它所引出的Looper、MessageQueue、Message

    0.引入 0.1.线程间通信的目的 首先,线程间通信要交流些什么呢? 解答这个问题要从为什么要有多线程开始,需要多线程的原因大概有这些 最早也最基本:有的任务需要大量的时间,但其实并不占用计算资源,比 ...

  4. Python并行编程(十二):进程同步

    1.基本概念 多个进程可以协同工作来完成一项任务,通常需要共享数据.所以在多进程之间保持数据的一致性就很重要,需要共享数据协同的进程必须以适当的策略来读写数据.同步原语和线程的库类似. - Lock: ...

  5. 锁、volatile、CAS 比较

    一.锁的劣势 (1) 在JDK1.5之前都是使用synchronized关键字保证同步的,这种通过使用一致的锁定协议来协调对共享状态的访问,可以确保无论哪个线程持有守 护变量的锁,都采用独占的方式来访 ...

  6. Mysql中datetime和timestamp区别

    DATETIME日期和时间的组合.支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'.MySQL以'YYYY-MM-DD HH:MM:SS'格式显示DA ...

  7. java-mybaits-00103-入门程序原生的【查、增、删、改】

    一.需求 实现以下功能: 根据用户id查询一个用户信息 根据用户名称模糊查询用户信息列表 添加用户 更新用户 删除用户 二.具体步骤 1.增加pom引用 2.增加log4j.properties # ...

  8. EOS 的网站及资料doc

    https://github.com/EOSIO/Documentation/blob/master/zh-CN/Roadmap.md https://bytemaster.github.io/bit ...

  9. Openstack(九)部署nova服务(控制节点)

    9.1nova服务介绍 nova是openstack最早的组件之一,nova分为控制节点和计算节点,计算节点通过nova computer进行虚拟机创建,通过libvirt调用kvm创建虚拟机,nov ...

  10. 跟我学Makefile(三)

    紧接着跟我学Makefile(二)继续学习:变量高级用法 (1)变量值的替换 :替换变量中的共有的部分,其格式是“$(var:a=b)”或是“${var:a=b}”,把变量“var”中所有以“a”字串 ...