【bzoj2243】 [SDOI2011]染色 树链剖分+线段树
来源:互联网 发布:苹果mac锁屏快捷键 编辑:程序博客网 时间:2024/05/19 03:45
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,表示x和y之间有一条无向边。
下面 行每行描述一个操作:
“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;
“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。
Output
对于每个询问操作,输出一行答案。
Sample Input
6 52 2 1 2 1 11 21 32 42 52 6Q 3 5C 2 1 1Q 3 5C 5 1 2Q 3 5
Sample Output
312
HINT
数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。
Source
第一轮day1
如果是序列的话就是线段树傻X题吧…
改成树上,就剖一下,区间修改+区间查询而已…
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int size=1000010;int head[size],nxt[size],to[size],tot=0;void build(int f,int t){ to[++tot]=t; nxt[tot]=head[f]; head[f]=tot;}int fa[size],sz[size],son[size],deep[size];int inseg[size],top[size];void dfs_1(int u,int f){ deep[u]=deep[f]+1; sz[u]=1; fa[u]=f; for(int i=head[u];i;i=nxt[i]) { int v=to[i]; if(v==f) continue; dfs_1(v,u); sz[u]+=sz[v]; if(!son[u]||sz[v]>sz[son[u]]) son[u]=v; }}int totp=0;void dfs_2(int u,int topu){ top[u]=topu; inseg[u]=++totp; if(!son[u]) return; dfs_2(son[u],topu); for(int i=head[u];i;i=nxt[i]) { int v=to[i]; if(v==fa[u]||v==son[u]) continue; dfs_2(v,v); }}struct segment{ int l,r; int ans,lc,rc,c;}tree[size];void update(int p){ tree[p].lc=tree[p<<1].lc; tree[p].rc=tree[p<<1|1].rc; if(tree[p<<1].rc==tree[p<<1|1].lc) tree[p].ans=tree[p<<1].ans+tree[p<<1|1].ans-1; else tree[p].ans=tree[p<<1].ans+tree[p<<1|1].ans;}void build_tree(int p,int l,int r){ tree[p].l=l; tree[p].r=r; if(l==r) { tree[p].ans=tree[p].lc=tree[p].rc=tree[p].c=0; return ; } int mid=(l+r)>>1; build_tree(p<<1,l,mid); build_tree(p<<1|1,mid+1,r); update(p);}void spread(int p){ if(tree[p].c) { tree[p<<1|1].ans=1; tree[p<<1|1].lc=tree[p].c; tree[p<<1|1].rc=tree[p].c; tree[p<<1|1].c=tree[p].c; tree[p<<1].ans=1; tree[p<<1].lc=tree[p].c; tree[p<<1].rc=tree[p].c; tree[p<<1].c=tree[p].c; tree[p].c=0; }}void change(int p,int l,int r,int c){ if(l<=tree[p].l&&tree[p].r<=r) { tree[p].ans=1; tree[p].lc=c; tree[p].rc=c; tree[p].c=c; return ; } spread(p); int mid=(tree[p].l+tree[p].r)>>1; if(l<=mid) change(p<<1,l,r,c); if(mid<r) change(p<<1|1,l,r,c); update(p);}int ask_ans(int p,int l,int r){ if(l<=tree[p].l&&tree[p].r<=r) { return tree[p].ans; } spread(p); int mid=(tree[p].l+tree[p].r)>>1; int ans=0; if(l<=mid&&mid<r) { if(tree[p<<1].rc==tree[p<<1|1].lc) ans+=ask_ans(p<<1,l,mid)+ask_ans(p<<1|1,mid+1,r)-1; else ans+=ask_ans(p<<1,l,mid)+ask_ans(p<<1|1,mid+1,r); } else if(l<=mid) ans+=ask_ans(p<<1,l,r); else if(mid<r) ans+=ask_ans(p<<1|1,l,r); return ans;}int ask_color(int p,int x){ if(tree[p].l==tree[p].r) { return tree[p].lc; } spread(p); int mid=(tree[p].l+tree[p].r)>>1; if(x<=mid) return ask_color(p<<1,x); else return ask_color(p<<1|1,x);}int find_ans(int x,int y){ int fx=top[x],fy=top[y]; int ans=0; while(fx!=fy) { if(deep[fx]<deep[fy]) swap(x,y),swap(fx,fy); ans+=ask_ans(1,inseg[fx],inseg[x]); if(ask_color(1,inseg[fx])==ask_color(1,inseg[fa[fx]])) ans--; x=fa[fx],fx=top[x]; } if(deep[x]>deep[y]) swap(x,y); ans+=ask_ans(1,inseg[x],inseg[y]); return ans;}void find_change(int x,int y,int c){ int fx=top[x],fy=top[y]; while(fx!=fy) { if(deep[fx]<deep[fy]) swap(x,y),swap(fx,fy); change(1,inseg[fx],inseg[x],c); x=fa[fx],fx=top[x]; } if(deep[x]>deep[y]) swap(x,y); change(1,inseg[x],inseg[y],c);}int data[size];int main(){ freopen("2243.in","r",stdin); freopen("2243.out","w",stdout); int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&data[i]); } for(int i=1;i<=n-1;i++) { int a,b; scanf("%d%d",&a,&b); build(a,b); build(b,a); } dfs_1(1,0); dfs_2(1,1); build_tree(1,1,n); for(int i=1;i<=n;i++) { change(1,inseg[i],inseg[i],data[i]); } while(m--) { char s[5]; scanf("%s",s); switch(s[0]) { case 'C': int l,r,c; scanf("%d%d%d",&l,&r,&c); if(inseg[l]>inseg[r]) swap(l,r); find_change(l,r,c); break; case 'Q': int a,b; scanf("%d%d",&a,&b); printf("%d\n",find_ans(a,b)); break; } } return 0;}/*6 52 2 1 2 1 11 21 32 42 52 6Q 3 5C 2 1 1Q 3 5C 5 1 2Q 3 5*/
0 0
- 【bzoj2243】 [SDOI2011]染色 树链剖分+线段树
- 【BZOJ2243】【SDOI2011】染色(树链剖分+线段树)
- 【BZOJ2243】[SDOI2011]染色【树链剖分】【线段树】
- bzoj2243 [SDOI2011]染色 (树链剖分+线段树)
- 树链剖分+线段树【SDOI2011】 bzoj2243 染色
- 【bzoj2243】【树链剖分】【线段树】SDOI2011染色
- bzoj2243: [SDOI2011]染色(树链剖分+线段树)
- [BZOJ2243][SDOI2011]染色(树剖+线段树)
- bzoj2243: [SDOI2011]染色 树链剖分
- 【BZOJ2243】[SDOI2011]染色 树链剖分
- 【BZOJ2243】【SDOI2011】染色 树链剖分
- 【SDOI2011】【BZOJ2243】【树链剖分】染色
- 【bzoj2243】【sdoi2011】染色【树链剖分】
- Bzoj2243[SDOI2011]染色:树链剖分
- [SDOI2011] [BZOJ2243] 染色 - 树链剖分
- BZOJ2243 【SDOI2011】染色 树链剖分
- BZOJ2243: [SDOI2011]染色 树链剖分
- bzoj2243 SDOI2011 染色 树链剖分
- 反射——Java高级开发必备知识
- MyEclipse 启动 tomcate 失败 解决方法
- Bootloader
- 你不知道的JavaScript--Item13 理解 prototype, getPrototypeOf 和__proto__
- 语音识别资料
- 【bzoj2243】 [SDOI2011]染色 树链剖分+线段树
- 排序算法之冒泡排序
- MD设计之ToolBar
- 外卖APP,别跟我谈什么用户粘度,他们有吗?
- Fedora9.0 tiny210环境搭建
- W3C测试题--jquery ajax JS错误集合
- Exception in thread "png-cruncher_2" java.lang.RuntimeException: Timed out while waiting for slave a
- flash文件制作笔记
- printf()、fprintf()和sprintf()的总结