[BZOJ2243]染色 做题笔记
2016-03-22 22:41
330 查看
·· / ·– ·· ·-·· ·-·· / ·–· · ·-· ··· ·· ··· - / ··- -· - ·· ·-·· / ·· / ·– ·· -·
题目来源:http://www.lydsy.com/JudgeOnline/problem.php?id=2243
线段树维护色块数量,区间最左端的颜色,区间最右端的颜色。合并区间时,如果左区间的最右端的颜色等于右区间的最左端的颜色,注意-1。
题目来源:http://www.lydsy.com/JudgeOnline/problem.php?id=2243
线段树维护色块数量,区间最左端的颜色,区间最右端的颜色。合并区间时,如果左区间的最右端的颜色等于右区间的最左端的颜色,注意-1。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=100010,inf=0x7fffffff; #define lch now<<1 #define rch now<<1|1 struct Tree { int col,l,r,num,lc,rc; }I[N<<2]; int n,m,num,a,b,tot,L,R,val,pos,cnt; int xx,yy,head ,ver[N<<1],nxt[N<<1]; int son ,top ,w ,C ; int dep ,fa ,sz ,id ; int Lc,Rc,u,v,c; void add(int u,int v) { ver[++tot]=v;nxt[tot]=head[u];head[u]=tot; } void dfs_1 (int u,int from) { sz[u]=1,son[u]=0,fa[u]=from; for (int i=head[u];i;i=nxt[i]) { int v=ver[i]; if (v==fa[u]) continue; dep[v]=dep[u]+1; fa[v]=u; dfs_1(v,u); sz[u]+=sz[v]; if (!son[u]||sz[son[u]]<sz[v]) son[u]=v; } } void dfs_2 (int u,int st) { w[u]=++cnt;top[u]=st;id[cnt]=u; if (son[u]) dfs_2(son[u],st); for (int i=head[u];i;i=nxt[i]) { int v=ver[i]; if (v==son[u]||v==fa[u]) continue; dfs_2(v,v); } } void pushup (int now) { I[now].lc=I[lch].lc;I[now].rc=I[rch].rc; int ans=I[lch].num+I[rch].num; if (I[lch].rc==I[rch].lc) ans--; I[now].num=ans; } void pushdown (int now) { if (!I[now].col) return;// I[lch].col=I[rch].col=I[now].col; I[lch].num=I[rch].num=1; I[lch].lc=I[lch].rc=I[now].lc;// I[rch].lc=I[rch].rc=I[now].lc;// I[now].col=0; } void build (int now,int l,int r) { I[now].l=l;I[now].r=r;I[now].num=0; if (l==r) return ; int mid=(l+r)>>1; build(lch,l,mid);build(rch,mid+1,r); } void change (int now,int l,int r,int x) { if (I[now].l==l&&I[now].r==r) { I[now].num=I[now].col=1; I[now].lc=I[now].rc=x; return ; } pushdown(now); int mid=(I[now].l+I[now].r)>>1; if (r<=mid) change(lch,l,r,x); else if (l>mid) change(rch,l,r,x); else change(lch,l,mid,x),change(rch,mid+1,r,x); pushup(now); } int query (int now,int l,int r,int L,int R) { if (I[now].l==L) Lc=I[now].lc; if (I[now].r==R) Rc=I[now].rc; if (I[now].l==l&&I[now].r==r) return I[now].num; pushdown(now); int mid=(I[now].l+I[now].r)>>1; if (r<=mid) return query(lch,l,r,L,R); else if (l>mid) return query(rch,l,r,L,R); else { int ans=query(lch,l,mid,L,R)+query(rch,mid+1,r,L,R); if (I[lch].rc==I[rch].lc) ans--; return ans; } pushup(now); } int Get (int u,int v,int opt,int c) { int ans=0; if (opt==1) { while (top[u]!=top[v]) { if (dep[top[u]]<dep[top[v]]) swap(u,v); change(1,w[top[u]],w[u],c); u=fa[top[u]]; } if (dep[u]>dep[v]) swap(u,v); change(1,w[u],w[v],c); } else { int ans1=-1,ans2=-1; while (top[u]!=top[v]) { if (dep[top[u]]<dep[top[v]]) swap(u,v),swap(ans1,ans2); int L=w[top[u]],R=w[u]; ans+=query(1,L,R,L,R); if (Rc==ans1) ans--; u=fa[top[u]],ans1=Lc; } if (dep[u]<dep[v]) swap(u,v),swap(ans1,ans2); ans+=query(1,w[v],w[u],w[v],w[u]); if (Rc==ans1) ans--;//注意判断 if (Lc==ans2) ans--;// } return ans; } int main () { char str[30]; scanf("%d%d",&n,&m); cnt=0;tot=1; for (int i=1;i<=n;i++) scanf("%d",&C[i]); for (int i=1;i<n;i++) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs_1(1,0); dfs_2(1,1); build(1,1,n); for (int i=1;i<=n;i++) change(1,w[i],w[i],C[i]); while (m--) { scanf("%s",str); if (str[0]=='C') { scanf("%d%d%d",&u,&v,&c); Get(u,v,1,c); } else { scanf("%d%d",&u,&v); printf("%d\n",Get(u,v,2,0)); } } return 0; }
相关文章推荐
- 面试题59:二叉树序列化
- Java day08 异常处理与正常代码分离 图形面积
- python 下的数据结构与算法---2:大O符号与常用算法和数据结构的复杂度速查表
- Django: 之数据库导入、迁移和联用
- leetcode——278—— First Bad Version
- 爬虫 Cookie 学习
- bootstraps对于低于IE9版本的支持
- 共同学习Java源码--常用数据类型--String(二)
- submit text3常用快捷键
- C# Stream 和 byte[] 之间的转换
- DR(Direct Routing)介绍
- 多播(组播)
- Codeforces 383E Vowels (容斥+莫比乌斯变换)
- 面向科研的编程技巧
- 3.16Java基础总结 IO全部
- 2016网易春招Java在线笔试回忆录
- OC中的load和initialize方法
- android面试题整理
- ExtJs之Ext.core.DomHelper.append
- Adaboost的意义