您的位置:首页 > 其它

HYSBZ - 2243 染色

2017-03-13 17:24 267 查看
给定一棵有n个节点的无根树和m个操作,操作有2类:

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

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

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

Input

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

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

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

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

“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<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lson root<<1
#define rson (root<<1)|1
using namespace std;
const int maxn=1e5+5;
struct node{
int to,nxt;
}ed[maxn<<1];
int head[maxn],cnt;
int dep[maxn],sz[maxn],son[maxn],p[maxn],top[maxn],fa[maxn];
int initcol[maxn],ndcol[maxn],pos;
void addedge(int u,int v){
ed[cnt].to=v;
ed[cnt].nxt=head[u];
head[u]=cnt++;
}
void dfs1(int u,int pre,int d){
dep[u]=d;
sz[u]=1;
fa[u]=pre;
for(int i=head[u];~i;i=ed[i].nxt){
int v=ed[i].to;
if(v!=pre){
dfs1(v,u,d+1);
sz[u]+=sz[v];
if(son[u]==-1||sz[son[u]]<sz[v])son[u]=v;
}
}
}
void dfs2(int u,int tp){
top[u]=tp;
p[u]=pos++;
initcol[p[u]]=ndcol[u];
if(son[u]==-1){
return ;
}
dfs2(son[u],tp);
for(int i=head[u];~i;i=ed[i].nxt){
int v=ed[i].to;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
struct T{
int l,r,lc,rc,mark,num;
}tree[maxn<<2];
void pushup(int root){
tree[root].lc=tree[lson].lc;
tree[root].rc=tree[rson].rc;
tree[root].num=tree[lson].num+tree[rson].num-(tree[lson].rc==tree[rson].lc);
return ;
}
void pushdown(int root){
if(tree[root].l==tree[root].r)return ;
if(tree[root].mark==0)return ;
tree[lson].mark=tree[rson].mark=tree[root].mark;
tree[lson].lc=tree[lson].rc=tree[rson].lc=tree[rson].rc=tree[root].mark;
tree[lson].num=tree[rson].num=1;
tree[root].mark=0;
return ;
}
void build(int l,int r,int root){
tree[root].l=l,tree[root].r=r;
tree[root].lc=initcol[l];
tree[root].rc=initcol[r];
tree[root].mark=0;
if(l==r){
tree[root].num=1;
return ;
}
int mid=l+r>>1;
build(l,mid,lson);
build(mid+1,r,rson);
pushup(root);
return ;
}
void update(int l,int r,int col,int root){
if(tree[root].l==l&&tree[root].r==r){
tree[root].lc=tree[root].rc=col;
tree[root].num=1;
tree[root].mark=col;
return ;
}
pushdown(root);
int mid=tree[root].l+tree[root].r>>1;
if(r<=mid)update(l,r,col,lson);
else if(l>mid)update(l,r,col,rson);
else {
update(l,mid,col,lson);
update(mid+1,r,col,rson);
}
pushup(root);
return ;
}
int ask(int a,int root){
if(a==tree[root].r)return tree[root].rc;
if(a==tree[root].l)return tree[root].lc;
pushdown(root);
int mid=tree[root].l+tree[root].r>>1;
if(a<=mid)return ask(a,lson);
else if(a>mid)return ask(a,rson);
}
int query(int l,int r,int root){
if(tree[root].l==l&&tree[root].r==r){
return tree[root].num;
}
pushdown(root);
int mid=(tree[root].l+tree[root].r)>>1;
if(r<=mid)return query(l,r,lson);
else if(l>mid)return query(l,r,rson);
else {
return query(l,mid,lson)+query(mid+1,r,rson)-(tree[lson].rc==tree[rson].lc);
}
}
void up(int u,int v,int col){
int f1=top[u],f2=top[v];
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
update(p[f1],p[u],col,1);
u=fa[f1];
f1=top[u];
}
if(dep[u]<dep[v])swap(u,v);
update(p[v],p[u],col,1);
}
int getnum(int u,int v){
int f1=top[u],f2=top[v];
int re=0;
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
re+=query(p[f1],p[u],1)-(ask(p[fa[f1]],1)==ask(p[f1],1));
u=fa[f1];
f1=top[u];
}
if(dep[u]<dep[v])swap(u,v);
re+=query(p[v],p[u],1);
return re;
}
int main()
{
memset(son,-1,sizeof(son));
memset(head,-1,sizeof(head));
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&ndcol[i]);
}
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
dfs1(1,0,0);
dfs2(1,1);
build(0,n,1);
while(m--){
char str[2];
int a,b,c;
scanf("%s%d%d",str,&a,&b);
if(str[0]=='C'){
scanf("%d",&c);
up(a,b,c);
}
else {
printf("%d\n",getnum(a,b));
}
getchar();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: