AC日记——[SDOI2011]染色 洛谷 P2486
2024-09-29 09:27:36
题目描述
输入输出格式
输入格式:
输出格式:
对于每个询问操作,输出一行答案。
输入输出样例
输入样例#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
说明
思路:
树剖+线段树维护区间颜色数量
来,上代码:
#include <cstdio>
#include <iostream>
#include <algorithm> #define maxn 200001 using namespace std; struct TreeNodeType {
int l,r,dis,lc,rc,flag,mid;
};
struct TreeNodeType tree[maxn<<]; struct EdgeType {
int to,next;
};
struct EdgeType edge[maxn<<]; int n,m,if_z,dis[maxn],flag[maxn],dis_[maxn];
int size[maxn],head[maxn],deep[maxn],f[maxn];
int cnt,tot,num,belong[maxn]; char Cget; inline void read_int(int &now)
{
now=,if_z=,Cget=getchar();
while(Cget>''||Cget<'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
now*=if_z;
} inline void edge_add(int from,int to)
{
edge[++num].to=from,edge[num].next=head[to],head[to]=num;
edge[++num].to=to,edge[num].next=head[from],head[from]=num;
} void search(int now,int fa)
{
int pos=cnt++;
deep[now]=deep[fa]+,f[now]=fa;
for(int i=head[now];i;i=edge[i].next)
{
if(edge[i].to==fa) continue;
search(edge[i].to,now);
}
size[now]=cnt-pos;
} void search_(int now,int chain)
{
belong[now]=chain,flag[now]=++cnt;
dis_[flag[now]]=dis[now];
int pos=;
for(int i=head[now];i;i=edge[i].next)
{
if(edge[i].to==f[now]) continue;
if(size[edge[i].to]>size[pos]) pos=edge[i].to;
}
if(pos!=) search_(pos,chain);
else return ;
for(int i=head[now];i;i=edge[i].next)
{
if(edge[i].to==f[now]||edge[i].to==pos) continue;
search_(edge[i].to,edge[i].to);
}
} inline void tree_up(int now)
{
if(tree[now<<].rc==tree[now<<|].lc)
{
tree[now].dis=tree[now<<].dis+tree[now<<|].dis-;
}
else
{
tree[now].dis=tree[now<<].dis+tree[now<<|].dis;
}
tree[now].lc=tree[now<<].lc,tree[now].rc=tree[now<<|].rc;
} inline void tree_down(int now)
{
if(tree[now].l==tree[now].r) return ;
tree[now<<].dis=,tree[now<<|].dis=;
tree[now<<].lc=tree[now<<].rc=tree[now].flag;
tree[now<<|].lc=tree[now<<|].rc=tree[now].flag;
tree[now<<].flag=tree[now<<|].flag=tree[now].flag;
tree[now].flag=;
} void tree_build(int now,int l,int r)
{
tree[now].l=l,tree[now].r=r;
if(l==r)
{
tree[now].lc=dis_[++cnt];
tree[now].rc=tree[now].lc;
tree[now].dis=;
return ;
}
tree[now].mid=(l+r)>>;
tree_build(now<<,l,tree[now].mid);
tree_build(now<<|,tree[now].mid+,r);
tree_up(now);
} void tree_change(int now,int l,int r,int x)
{
if(tree[now].l==l&&tree[now].r==r)
{
tree[now].dis=,tree[now].flag=x;
tree[now].lc=tree[now].rc=x;
return ;
}
if(tree[now].flag) tree_down(now);
if(l>tree[now].mid) tree_change(now<<|,l,r,x);
else if(r<=tree[now].mid) tree_change(now<<,l,r,x);
else
{
tree_change(now<<,l,tree[now].mid,x);
tree_change(now<<|,tree[now].mid+,r,x);
}
tree_up(now);
} int tree_query(int now,int l,int r)
{
if(tree[now].l==l&&tree[now].r==r)
{
return tree[now].dis;
}
if(tree[now].flag) tree_down(now);
tree_up(now);
if(l>tree[now].mid) return tree_query(now<<|,l,r);
else if(r<=tree[now].mid) return tree_query(now<<,l,r);
else
{
int ld=tree_query(now<<,l,tree[now].mid);
int rd=tree_query(now<<|,tree[now].mid+,r);
if(tree[now<<].rc==tree[now<<|].lc) return ld+rd-;
else return ld+rd;
}
} int tree_query_color(int now,int to)
{
if(tree[now].l==tree[now].r&&tree[now].l==to)
{
return tree[now].lc;
}
if(tree[now].flag) tree_down(now);
tree_up(now);
if(to>tree[now].mid) return tree_query_color(now<<|,to);
else return tree_query_color(now<<,to);
} inline void solve_change(int x,int y,int z)
{
while(belong[x]!=belong[y])
{
if(deep[belong[x]]<deep[belong[y]]) swap(x,y);
tree_change(,flag[belong[x]],flag[x],z);
x=f[belong[x]];
}
tree_change(,min(flag[x],flag[y]),max(flag[x],flag[y]),z);
} inline int solve_query(int x,int y)
{
int ans=;
while(belong[x]!=belong[y])
{
if(deep[belong[x]]<deep[belong[y]]) swap(x,y);
ans+=tree_query(,flag[belong[x]],flag[x]);
if(tree_query_color(,flag[belong[x]])==tree_query_color(,flag[f[belong[x]]])) ans--;
x=f[belong[x]];
}
ans+=tree_query(,min(flag[x],flag[y]),max(flag[x],flag[y]));
return ans;
} int main()
{
read_int(n),read_int(m);
for(int i=;i<=n;i++) read_int(dis[i]);
int from,to,pos;
for(int i=;i<n;i++)
{
read_int(from),read_int(to);
edge_add(from,to);
}
search(,),cnt=,search_(,),cnt=,tree_build(,,n);
char type;
for(int i=;i<=m;i++)
{
cin>>type;
if(type=='C')
{
read_int(from),read_int(to),read_int(pos);
solve_change(from,to,pos);
}
else
{
read_int(from),read_int(to);
printf("%d\n",solve_query(from,to));
}
}
return ;
}
最新文章
- Base64编码
- 转:ibatis的cacheModel
- iis7 64位 操作excel的一系列问题(未完待续)
- Spirit - 腾讯移动 Web 整体解决方案
- hadoop启动jobhistoryserver
- UVa 11384 Help is needed for Dexter 正整数序列
- visio 改变画布大小
- linq 动态排序
- jsp带参转链接
- XPath总结(转)
- 通过CSS实现各种方向的三角形
- ural1090 In the Army Now
- 使用redis所维护的代理池抓取微信文章
- Linux下的 >;, >;>;, <;, ps, |, grep, /dev/null
- Flutter自定义路由PageRouteBuilder
- gRPC奇怪的编译命令protoc
- vue2.0 之条件渲染
- 【转】jquery cookie操作
- Spring MVC中使用errors标签
- oc总结 --oc基础语法相关知识