您的位置:首页 > 其它

洛谷P2486 [SDOI2011]染色

2017-12-26 23:24 323 查看


题目描述




输入输出格式

输入格式:



输出格式:

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


输入输出样例

输入样例#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



说明





典型的树链剖分+线段树,线段树维护 区间左右端点颜色 和 区间颜色数。

注意:当 上传或求颜色数 时,若 左区间右端点颜色 == 右区间左端点颜色,结果要减1 。。。

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#define LSON rt<<1
#define RSON rt<<1|1
#define DATA(x) b[x].data
#define DATAL(x) b[x].left
#define DATAR(x) b[x].right
#define SIGN(x) b[x].c
#define LSIDE(x) b[x].l
#define RSIDE(x) b[x].r
#define MAXN 100010
using namespace std;
int n,m,c=1,d=1;
int val[MAXN],head[MAXN],id[MAXN],top[MAXN],deep[MAXN],son[MAXN],fa[MAXN],size[MAXN];
struct node1{
int next,to;
}a[MAXN<<1];
struct node2{
int data,left,right,c;
int l,r;
}b[MAXN<<2];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
void add(int u,int v){
a[c].to=v;
a[c].next=head[u];
head[u]=c++;
a[c].to=u;
a[c].next=head[v];
head[v]=c++;
}
void dfs1(int rt){
son[rt]=0;size[rt]=1;
for(int i=head[rt];i;i=a[i].next){
int will=a[i].to;
if(!deep[will]){
deep[will]=deep[rt]+1;
fa[will]=rt;
dfs1(will);
size[rt]+=size[will];
if(size[will]>size[son[rt]])son[rt]=will;
}
}
}
void dfs2(int rt,int f){
id[rt]=d++;top[rt]=f;
if(son[rt])dfs2(son[rt],f);
for(int i=head[rt];i;i=a[i].next){
int will=a[i].to;
if(will!=son[rt]&&will!=fa[rt])
dfs2(will,will);
}
}
void pushup(int rt){
DATAL(rt)=DATAL(LSON);DATAR(rt)=DATAR(RSON);
DATA(rt)=DATA(LSON)+DATA(RSON);
if(DATAR(LSON)==DATAL(RSON))DATA(rt)--;
}
void pushdown(int rt){
if(!SIGN(rt)||LSIDE(rt)==RSIDE(rt))return;
SIGN(LSON)=DATAL(LSON)=DATAR(LSON)=SIGN(rt);
DATA(LSON)=1;
SIGN(RSON)=DATAL(RSON)=DATAR(RSON)=SIGN(rt);
DATA(RSON)=1;
SIGN(rt)=0;
}
void buildtree(int l,int r,int rt){
int mid;
LSIDE(rt)=l;
RSIDE(rt)=r;
if(l==r){
DATA(rt)=0;
return;
}
mid=l+r>>1;
buildtree(l,mid,LSON);
buildtree(mid+1,r,RSON);
pushup(rt);
}
void update(int l,int r,int c,int rt){
int mid;
if(l<=LSIDE(rt)&&RSIDE(rt)<=r){
SIGN(rt)=DATAL(rt)=DATAR(rt)=c;
DATA(rt)=1;
return;
}
pushdown(rt);
mid=LSIDE(rt)+RSIDE(rt)>>1;
if(l<=mid)update(l,r,c,LSON);
if(mid<r)update(l,r,c,RSON);
pushup(rt);
}
int query(int l,int r,int rt){
int mid,ans=0;
if(l<=LSIDE(rt)&&RSIDE(rt)<=r)
return DATA(rt);
pushdown(rt);
mid=LSIDE(rt)+RSIDE(rt)>>1;
if(l<=mid)ans+=query(l,r,LSON);
if(mid<r)ans+=query(l,r,RSON);
if(l<=mid&&mid<r&&DATAR(LSON)==DATAL(RSON))ans--;
return ans;
}
int qcolour(int l,int r,int rt){
int mid;
if(l<=LSIDE(rt)&&RSIDE(rt)<=r)
return DATAL(rt);
pushdown(rt);
mid=LSIDE(rt)+RSIDE(rt)>>1;
if(l<=mid)return qcolour(l,r,LSON);
else return qcolour(l,r,RSON);
}
void work1(int x,int y,int z){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])swap(x,y);
update(id[top[x]],id[x],z,1);
x=fa[top[x]];
}
if(deep[x]>deep[y])swap(x,y);
update(id[x],id[y],z,1);
return;
}
void work2(int x,int y){
int s=0,left,right;
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])swap(x,y);
s+=query(id[top[x]],id[x],1);
left=qcolour(id[top[x]],id[top[x]],1);
right=qcolour(id[fa[top[x]]],id[fa[top[x]]],1);
x=fa[top[x]];
if(left==right)s--;
}
if(deep[x]>deep[y])swap(x,y);
s+=query(id[x
e016
],id[y],1);
printf("%d\n",s==0?1:s);
return;
}
void work(){
char ch[2];
int x,y,z;
while(m--){
scanf("%s",ch);x=read();y=read();
if(ch[0]=='C'){
z=read();
work1(x,y,z);
}
if(ch[0]=='Q')work2(x,y);
}
}
void init(){
int u,v;
n=read();m=read();
for(int i=1;i<=n;i++)val[i]=read();
for(int i=1;i<n;i++){
u=read();v=read();
add(u,v);
}
deep[1]=fa[1]=1;
dfs1(1);
dfs2(1,1);
buildtree(1,n,1);
for(int i=1;i<=n;i++)update(id[i],id[i],val[i],1);
}
int main(){
init();
work();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: