【BZOJ 2243】染色 - 树链剖分+线段树
来源:互联网 发布:js 0开头数字转字符串 编辑:程序博客网 时间:2024/06/10 06:07
#include <cstdio>#include <cstring>#include <cstdlib>using namespace std;const int N=100001;int n,m,color[N]; //Basicstruct G{ int v,nxt;}map[N+N];int hd[N],tt; //Graphint son[N],dep[N],pre[N],size[N];int tid[N],top[N],num; //Chainstruct T{ int l,r; int lc,rc,tag; int cnt;}tr[N<<2]; //Segment Treeinline int read(void){ int s=0,f=1; char c=getchar(); for (;c<'0'||c>'9';c=getchar()) if (c=='-') f=-1; for (;'0'<=c&&c<='9';c=getchar()) s=(s<<1)+(s<<3)+c-'0'; return s*f;}inline void ins(int u,int v){ map[++tt].v=v; map[tt].nxt=hd[u]; hd[u]=tt;}void find(int now,int ht){ dep[now]=ht,size[now]=1; for (int k=hd[now];k;k=map[k].nxt) if (!size[map[k].v]) { find(map[k].v,ht+1); size[now]+=size[map[k].v]; pre[map[k].v]=now; if (!son[now]||size[son[now]]<size[map[k].v]) son[now]=map[k].v; }}void cut(int now,int anc){ top[now]=anc,tid[now]=++num; if (son[now]) cut(son[now],anc); for (int k=hd[now];k;k=map[k].nxt) if (!tid[map[k].v]) cut(map[k].v,map[k].v);}inline void clear(int now){ if (tr[now].tag==-1) return; tr[now<<1].tag=tr[now<<1|1].tag=tr[now].tag; tr[now<<1].lc=tr[now<<1].rc=tr[now].tag; tr[now<<1|1].lc=tr[now<<1|1].rc=tr[now].tag; tr[now<<1].cnt=tr[now<<1|1].cnt=1; tr[now].tag=-1;}void build(int now,int l,int r){ tr[now].l=l; tr[now].r=r; tr[now].tag=-1; if (l^r) { int mid=l+r>>1; build(now<<1,l,mid); build(now<<1|1,mid+1,r); }}void ins(int now,int l,int r,int c){ if (l<=tr[now].l&&tr[now].r<=r) { tr[now].tag=tr[now].lc=tr[now].rc=c; tr[now].cnt=1; return; } clear(now); int mid=tr[now].l+tr[now].r>>1; if (l<=mid) ins(now<<1,l,r,c); if (mid<r) ins(now<<1|1,l,r,c); tr[now].lc=tr[now<<1].lc; tr[now].rc=tr[now<<1|1].rc; tr[now].cnt=tr[now<<1].cnt+tr[now<<1|1].cnt-(tr[now<<1].rc==tr[now<<1|1].lc);}void init(void){ n=read(),m=read(); for (int i=1;i<=n;i++) color[i]=read(); int u,v; for (int i=1;i<n;i++) { u=read(),v=read(); ins(u,v),ins(v,u); } find(1,1); cut(1,1); build(1,1,n); for (int i=1;i<=n;i++) ins(1,tid[i],tid[i],color[i]);}inline int LCA(int x,int y){ for (;top[x]^top[y];) if (dep[top[x]]>dep[top[y]]) x=pre[top[x]]; else y=pre[top[y]]; return dep[x]<dep[y]?x:y;}int query(int now,int l,int r){ if (l<=tr[now].l&&tr[now].r<=r) return tr[now].cnt; clear(now); int mid=tr[now].l+tr[now].r>>1,sum=0; if (l<=mid) sum+=query(now<<1,l,r); if (mid<r) sum+=query(now<<1|1,l,r); if (l<=mid&&mid<r) sum-=tr[now<<1].rc==tr[now<<1|1].lc; return sum;}int findcolor(int now,int loc){ if (tr[now].l==tr[now].r) return tr[now].tag; clear(now); int mid=tr[now].l+tr[now].r>>1; return findcolor(now<<1|(loc<=mid?0:1),loc);}void work(void){ char c; int x,y,z,p,res,uc,dc; for (int i=1;i<=m;i++) { scanf("\n%c",&c); if (c=='C') { x=read(),y=read(),z=read(),p=LCA(x,y); for (;top[x]^top[p];x=pre[top[x]]) ins(1,tid[top[x]],tid[x],z); for (;top[y]^top[p];y=pre[top[y]]) ins(1,tid[top[y]],tid[y],z); ins(1,tid[p],x^p?tid[x]:tid[y],z); } else { x=read(),y=read(),p=LCA(x,y); uc=dc=-1,res=0; for (;top[x]^top[p];x=pre[top[x]]) { if (uc^-1) { dc=findcolor(1,tid[x]); res-=uc==dc; } res+=query(1,tid[top[x]],tid[x]); uc=findcolor(1,tid[top[x]]); } dc=findcolor(1,tid[x]); res-=uc==dc; uc=dc=-1; for (;top[y]^top[p];y=pre[top[y]]) { if (uc^-1) { dc=findcolor(1,tid[y]); res-=uc==dc; } res+=query(1,tid[top[y]],tid[y]); uc=findcolor(1,tid[top[y]]); } dc=findcolor(1,tid[y]); res-=uc==dc; res+=query(1,tid[p],x^p?tid[x]:tid[y]); printf("%d\n",res); } }}int main(void){ init(); work(); return 0;}
0 0
- BZOJ 2243 染色(树链剖分+线段树)
- 【BZOJ 2243】染色 - 树链剖分+线段树
- bzoj 2243: [SDOI2011]染色 树链剖分+线段树
- Bzoj 2243: [SDOI2011]染色(树链剖分+线段树)
- BZOJ 2243: [SDOI2011]染色 树链剖分+线段树
- [BZOJ]2243 染色 树链剖分+线段树
- BZOJ 2243 染色 线段树+树链剖分
- BZOJ 2243 染色(树链剖分+线段树区间合并)
- BZOJ 2243 染色(树链剖分+线段树区间更新)
- BZOJ 2243 [SDOI2011]染色 树链剖分+LCA+区间合并线段树
- BZOJ 2243: [SDOI2011]染色 (树链剖分,点权,线段树)
- bzoj 2243: [SDOI2011]染色 (树链剖分+线段树)
- bzoj 2243 [SDOI2011]染色 (线段树 + 树链剖分)
- bzoj 2243 [SDOI2011]染色 树剖+线段树
- BZOJ 8843 染色 [树链剖分+区间线段树]
- BZOJ-2243: [SDOI2011]染色 (树链剖分 入门题 线段树 区间修改查询 维护端点值)
- BZOJ 2243 染色 树链剖分
- bzoj 2243 染色(树链剖分)
- linux vmplice 示例
- DQL数据查询语言(二)及数据的备份与恢复
- linux 复习杂记(一) linux中的进程
- http部分内容总结
- 【DP】[USACO 2016 February Contest, Gold]Circular Barn Revisited
- 【BZOJ 2243】染色 - 树链剖分+线段树
- Linux的文本编辑命令除了vi(vim),还有哪些?
- 2016-3-12 Python学习
- Cocos2dx-- 3.0前后对比
- Python简单介绍
- Java程序员应该知道的10个Eclipse调试技巧
- Java中处理异常(try/catch)的快捷键
- lamp环境快速搭建
- Qt中文乱码