给定一棵有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. 3.html+.ashx(删除学生信息)

    C03ListStu.ashx 0:false(删除);1:true(正常). (数据库里定义个BOOL型,TRUE表示正常FALSE表示删除) <html> <head> & ...

  2. Java 中编程的格式

    Java 编程注意的格式: 1.大括号对齐 2.遇到{ 缩进Tab 3.程序块之间加空行 4.并排之间加空格 5.运算符之间加空格 6.{ 之间加空格 7.成对编程 ({ }) 8.类名首字母大写 9 ...

  3. Treasure Exploration---poj2594(传递闭包Floyd+最小路径覆盖)

    题目链接:http://poj.org/problem?id=2594 在外星上有n个点需要机器人去探险,有m条单向路径.问至少需要几个机器人才能遍历完所有的点,一个点可以被多个机器人经过(这就是和单 ...

  4. Python开发【数据结构】:算法(一)

    算法基础 1.什么是算法? 算法(Algorithm):一个计算过程,解决问题的方法 2.复习:递归 递归的两个特点: 调用自身 结束条件 两个重要递归函数的对比: # 由大到小 def func3( ...

  5. 安装Ruby、Sass在WebStrom添加Watcher实现编辑scss文件时自动生成.map和压缩后的.css文件

    前言 这段时间一直在看Bootstrap,V3官方直接提供了Less版本的源码,就先将Less学完了,很简单的语法,学习写Demo都是在Webstorm里写的,配置了Watcher自动编译(详见< ...

  6. word安装楷体gb2312方法。

    1:下载:楷体gb2312.http://www.downza.cn/soft/7732.html 2: 双击安装,将会下载楷体2312  的压缩文件,解压得到楷体2312.ttf. 3:  打开控制 ...

  7. 分布式版本管理git学习资料整理推荐

    一.什么是git? Git is a free and open source distributed version control system designed to handle everyt ...

  8. Linux系统——公网定制化yum仓库部署

    1)搭建公网源yum仓库 安装wget aliyun源 # wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel ...

  9. Python:笔记(6)——正则表达式

    Python:笔记(6)——正则表达式 re模块 re模块用于在字符串中执行基于正则表达式模式的匹配和替换. 使用原始字符串 正则表达式使用 \ 对特殊字符进行转义,比如,为了匹配字符串 ‘pytho ...

  10. Java实现动态规划法求解0/1背包问题

    摘要: 使用动态规划法求解0/1背包问题. 难度: 初级 0/1背包问题的动态规划法求解,前人之述备矣,这里所做的工作,不过是自己根据理解实现了一遍,主要目的还是锻炼思维和编程能力,同时,也是为了增进 ...