给定一棵有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. State of the official Elasticsearch Java clients

    Elasticsearch Java Clients | Elastic https://www.elastic.co/blog/state-of-the-official-elasticsearch ...

  2. talib 中文文档(九):Volume Indicators 成交量指标

    Volume Indicators 成交量指标 AD - Chaikin A/D Line 量价指标 函数名:AD 名称:Chaikin A/D Line 累积/派发线(Accumulation/Di ...

  3. Python开发【数据结构】:基础

    数据结构 什么是数据结构? 简单来说,数据结构就是设计数据以何种方式组织并存储在计算机中. 比如:列表.集合与字典等都是一种数据结构 N.Wirth: “程序=数据结构+算法” 列表 列表:在其他编程 ...

  4. day15(Mysql学习)

      day15-MySQL   数据库   1 数据库概念(了解) 1.1 什么是数据库 数据库就是用来存储和管理数据的仓库! 数据库存储数据的优先: 可存储大量数据: 方便检索: 保持数据的一致性. ...

  5. linux route命令的使用详解 添加永久静态路由 tracert traceroute

    linux route命令的使用详解 添加永久静态路由  tracert  traceroute route -n    Linuxroute  print  Windows traceroute  ...

  6. Atom飞行手册翻译

    https://www.w3cschool.cn/atomflightmanualzhcn/

  7. Python之traceback错误堆栈信息处理

    一.Python中的异常栈跟踪 之前在做Java的时候,异常对象默认就包含stacktrace相关的信息,通过异常对象的相关方法printStackTrace()和getStackTrace()等方法 ...

  8. POJ1006——Biorhythms(中国剩余定理)

    Biorhythms Description人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23天.28天和33天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色. ...

  9. http之url和uri

    HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接.URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息 URL,全称是U ...

  10. 表单验证—js循环所有表单验证

    [封装为表单验证的专用js,所有表单页面都可以调用] 1.表单 <form id="regForm" method="post" action=" ...