博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
染色(bzoj 2243)
阅读量:4511 次
发布时间:2019-06-08

本文共 2973 字,大约阅读时间需要 9 分钟。

Description

 

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

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

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

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

 

Input

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

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

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

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

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

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

 

Output

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

 

Sample Input

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

Sample Output

3
1
2

HINT

 

数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

#include
#include
#define N 100010using namespace std;int a[N],head[N],fa[N],son[N],dep[N],pos[N],top[N],lco[N*4],rco[N*4],sum[N*4],tag[N*4],n,m,sz;struct node{ int to,pre;};node e[N*2];void add(int i,int x,int y){ e[i].to=y; e[i].pre=head[x]; head[x]=i;}void dfs1(int x){ son[x]=1; for(int i=head[x];i;i=e[i].pre){ int v=e[i].to; if(fa[x]==v) continue; fa[v]=x;dep[v]=dep[x]+1; dfs1(v); son[x]+=son[v]; }}void dfs2(int x,int chain){ ++sz;pos[x]=sz;top[x]=chain;int k=0,maxn=0; for(int i=head[x];i;i=e[i].pre) if(fa[x]!=e[i].to&&son[e[i].to]>maxn){ k=e[i].to;maxn=son[e[i].to]; } if(!k) return; dfs2(k,chain); for(int i=head[x];i;i=e[i].pre) if(fa[x]!=e[i].to&&e[i].to!=k) dfs2(e[i].to,e[i].to);}void pushup(int k){ lco[k]=lco[k*2];rco[k]=rco[k*2+1]; sum[k]=sum[k*2]+sum[k*2+1]; if(rco[k*2]==lco[k*2+1])sum[k]--;}void pushdown(int k){ if(!tag[k]) return; tag[k*2]=tag[k*2+1]=tag[k]; lco[k*2]=lco[k*2+1]=tag[k]; rco[k*2]=rco[k*2+1]=tag[k]; sum[k*2]=sum[k*2+1]=1; tag[k]=0;}void change(int l,int r,int k,int x,int y,int v){ if(l>=x&&r<=y){ tag[k]=lco[k]=rco[k]=v; sum[k]=1; return; } pushdown(k); int mid=l+r>>1; if(x<=mid) change(l,mid,k*2,x,y,v); if(y>mid) change(mid+1,r,k*2+1,x,y,v); pushup(k);}int query(int l,int r,int k,int x,int y){ if(l==x&&r==y)return sum[k]; pushdown(k); int mid=l+r>>1; if(y<=mid) return query(l,mid,k*2,x,y); else if(x>mid) return query(mid+1,r,k*2+1,x,y); else { int ans=query(l,mid,k*2,x,mid)+query(mid+1,r,k*2+1,mid+1,y); if(rco[k*2]==lco[k*2+1]) ans--; return ans; }}int find(int l,int r,int k,int x){ if(l==r)return lco[k]; pushdown(k); int mid=l+r>>1; if(x<=mid) return find(l,mid,k*2,x); else return find(mid+1,r,k*2+1,x);}void xiugai(int x,int y,int v){ while(top[x]!=top[y]){ if(dep[top[x]]
dep[y]) swap(x,y); change(1,n,1,pos[x],pos[y],v);}int qiuhe(int x,int y){ int ans=0; while(top[x]!=top[y]){ if(dep[top[x]]
dep[y]) swap(x,y); ans+=query(1,n,1,pos[x],pos[y]); return ans;}int main(){ freopen("jh.in","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i

 

转载于:https://www.cnblogs.com/harden/p/6407836.html

你可能感兴趣的文章
Python——thread
查看>>
Python网络编程(4)——异步编程select & epoll
查看>>
为什么使用接口编程
查看>>
Flash Builder 4.6/4.7 注释以及字体大小修改
查看>>
解决Bug:Size of a request header field exceeds server limit
查看>>
利用rsync+inotify实现数据实时同步脚本文件
查看>>
firefox+firebug
查看>>
BZOJ 4008: [HNOI2015]亚瑟王
查看>>
中国智能车未来挑战赛——复杂交通环境认知基础能力离线测试
查看>>
app之间的跳转
查看>>
用yarn代替cnpm,cnpm漏包有点严重
查看>>
hibernate的基本使用
查看>>
Spark 2.6.1 源代码在 eclipse 的配置
查看>>
leetcode542 01 Matrix
查看>>
sql server 2008语言基础: T-sql语言基础2简单技巧
查看>>
Typescript + React-Router + Webpack 实现按需打包/加载
查看>>
underscore
查看>>
springboot项目如何在tomcat6中部署成功
查看>>
神器metasploit中Msfvenom 的用法(外文翻译转)
查看>>
[项目管理] 布鲁克斯法则
查看>>