题目描述

给定一棵有n个节点的无根树和m个操作,操作有2类:

1、将节点a到节点b路径上所有点都染成颜色c;

2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。

请你写一个程序依次完成这m个操作。

输入输出格式

输入格式:

第一行包含2个整数n和m,分别表示节点数和操作数;

第二行包含n个正整数表示n个节点的初始颜色

下面 行每行包含两个整数x和y,表示xy之间有一条无向边。

下面 行每行描述一个操作:

“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;

“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。

输出格式:

对于每个询问操作,输出一行答案。

输入输出样例

输入样例#1:

6 5
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
输出样例#1:

3
1
2

说明

//这个题面一半来自洛谷,一半来自BZOJ

解题思路

  树剖套线段树。这题重点在线段树上。线段树的每个节点存下此节点表示的区间范围l、r,这个区间内颜色块数num,l处的颜色lc,r处的颜色rc。

  然后从合并两个区间的信息时,特判如果接口处颜色相同,则当前区间num等于两个子区间num之和减一,不相等就不减一(语文不好,勉强看吧)

源代码

#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm> int n,m; struct Edge{
int next,to;
}e[];
int head[]={},cnt=;
void add(int u,int v)
{
e[cnt]={head[u],v};
head[u]=cnt++;
}
int color[]={};
struct tree{
int fa;
int w;
int dep;
int num_to;
int wson;
int top;
int id;
}t[]; void dfs1(int fa,int u,int dep)
{
t[u].fa=fa;
t[u].dep=dep;
t[u].num_to=;
t[u].wson=-;
int max_to=,num_son=;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v==fa) continue;
num_son++;
dfs1(u,v,dep+);
int temp=t[v].num_to;
t[u].num_to+=temp;
if(temp>max_to) t[u].wson=v,max_to=temp;
}
}
int id=;
void dfs2(int u,int top)
{
t[u].top=top;
t[u].id=id;
color[id]=t[u].w;
id++;
if(t[u].wson==-) return;
dfs2(t[u].wson,top);
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v==t[u].fa||v==t[u].wson) continue;
dfs2(v,v);
}
} struct stree{
int l,r;
int lc,rc;//边界l、r的颜色
int num;//区间内色块数
}s[];
int lazy[]={};//区间染色lazy
void maketree(int x,int l,int r)
{
s[x].l=l,s[x].r=r;
s[x].lc=color[l],s[x].rc=color[r];
if(l==r)
{
s[x].num=;
return;
}
int mid=l+r>>;
maketree(x<<,l,mid);
maketree(x<<|,mid+,r);
s[x].num=s[x<<].num+s[x<<|].num-(s[x<<].rc==s[x<<|].lc);
}
void pushdown(int x)
{
int ls=x<<,rs=ls|;
s[rs].num=s[ls].num=;
s[ls].lc=s[ls].rc=s[rs].rc=s[rs].lc=lazy[ls]=lazy[rs]=lazy[x];
lazy[x]=;
}
int query(int x,int l,int r)
{
if(l>s[x].r||r<s[x].l) return ;
if(l<=s[x].l&&s[x].r<=r) return s[x].num;
if(lazy[x]) pushdown(x);
int ans=query(x<<,l,r)+query(x<<|,l,r);
if(l<=s[x<<].r&&r>=s[x<<|].l&&s[x<<].rc==s[x<<|].lc) ans--;
return ans;
}
int query_color(int x,int pos)
{
int l=s[x].l,r=s[x].r;
if(l==r) return s[x].lc;
int mid=l+r>>;
if(lazy[x]) pushdown(x);
if(pos<=mid) return query_color(x<<,pos);
else return query_color(x<<|,pos);
}
void update(int x,int l,int r,int c)
{
if(l>s[x].r||r<s[x].l) return;
if(l<=s[x].l&&s[x].r<=r)
{
lazy[x]=c;
s[x].num=;
s[x].lc=s[x].rc=c;
return;
}
if(lazy[x]) pushdown(x);
update(x<<,l,r,c),update(x<<|,l,r,c);
s[x].lc=s[x<<].lc;
s[x].rc=s[x<<|].rc;
s[x].num=s[x<<].num+s[x<<|].num-(s[x<<].rc==s[x<<|].lc);
} void C(int x,int y,int c)
{
while(t[x].top!=t[y].top)
{
if(t[t[y].top].dep<t[t[x].top].dep) std::swap(x,y);//y的top更深
update(,t[t[y].top].id,t[y].id,c);
y=t[t[y].top].fa;
}
if(t[y].id<t[x].id) std::swap(x,y);
update(,t[x].id,t[y].id,c);
}
int Q(int x,int y)
{
int ans=;
while(t[x].top!=t[y].top)
{
if(t[t[y].top].dep>t[t[x].top].dep) std::swap(x,y);//x的top更深
ans+=query(,t[t[x].top].id,t[x].id)-(query_color(,t[t[x].top].id)==query_color(,t[t[t[x].top].fa].id));
x=t[t[x].top].fa;
}
if(t[y].id<t[x].id) std::swap(x,y);
ans+=query(,t[x].id,t[y].id);
return ans==?:ans;
} int main()
{
//freopen("test.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&t[i].w);
for(int i=,u,v;i<n;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs1(,,);
dfs2(,);
maketree(,,n);
for(int i=,a,b,c;i<=m;i++)
{
char mode[];
scanf("%s",mode);
if(mode[]=='Q')
{
scanf("%d%d",&a,&b);
printf("%d\n",Q(a,b));
}
else
{
scanf("%d%d%d",&a,&b,&c);
C(a,b,c);
}
}
return ;
}

洛谷 P2486 BZOJ 2243 [SDOI2011]染色的更多相关文章

  1. BZOJ 2243: [SDOI2011]染色 [树链剖分]

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

  2. bzoj 2243 [SDOI2011]染色(树链剖分,线段树)

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

  3. Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树

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

  4. bzoj 2243: [SDOI2011]染色 线段树区间合并+树链剖分

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

  5. bzoj 2243: [SDOI2011]染色 (树链剖分+线段树 区间合并)

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

  6. BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  7. BZOJ 2243: [SDOI2011]染色 树链剖分+线段树区间合并

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

  8. 洛谷 P2486 [SDOI2011]染色/bzoj 2243: [SDOI2011]染色 解题报告

    [SDOI2011]染色 题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同 ...

  9. bzoj 2243 [SDOI2011]染色(树链剖分+线段树合并)

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

随机推荐

  1. 【HDU 1007】 Quoit Design

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1007 [算法] 答案为平面最近点对距离除以2 [代码] #include <algorith ...

  2. JS连续滚动幻灯片:原理与实现

    什么是连续滚动幻灯片?打开一些网站的首页,你会发现有一块这样的区域:一张图片,隔一段时间滑动切换下一张:同时,图片两端各有一个小按钮,供你手动点选下一张:底部有一排小圆圈,供你选定特定的某帧图片.这就 ...

  3. assistant: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by

    [oracle@oracledb button]$ assistantassistant: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' no ...

  4. 【知识总结】多项式全家桶(二)(ln和exp)

    上一篇:[知识总结]多项式全家桶(一)(NTT.加减乘除和求逆) 一.对数函数\(\ln(A)\) 求一个多项式\(B(x)\),满足\(B(x)=\ln(A(x))\). 这里需要一些最基本的微积分 ...

  5. ACM_填格子

    填格子 Time Limit: 2000/1000ms (Java/Others) Problem Description: 在一个n*n格子里边已经填了部分大写字母,现在给你个任务:把剩下的格子也填 ...

  6. Jquery和Ajax的关系!

    Jquery是一种JavaScript框架,而Ajax(Asynchronous JavaScript and XML)是异步JavaScript和XML. Jquery是JavaScript的框架, ...

  7. android黑科技系列——获取加固后应用App的所有方法信息

    一.前言 在逆向应用的时候,我们有时候希望能够快速定位到应用的关键方法,在之前我已经详细介绍了一个自己研发的代码动态注入工具icodetools,来进行动态注入日志信息到应用中,不了解的同学可以查看这 ...

  8. Angular——数据绑定

    基本介绍 angularjs可以实现数据的双向绑定:(1)视图到模型的数据绑定,(2)模型到数据的绑定 基本使用 1.ng-model可以实现视图到模型的数据传输 2.{{name}}可以实现模型到视 ...

  9. html5——:hover事件触发自己的:afert伪元素事件

    :hover事件触发自己的:afert伪元素事件中间是没有空格的

  10. python PIL相关操作

    项目中需要用python生成二维码,这里记录一下相关PIL相关操作. RGBA问题: 需要将图片A粘贴到图片B上,之前没有注意透明度问题,A的背景是透明的,粘贴到B上后,A的周围是黑的.后来才发现是P ...