【BZOJ】2243 [SDOI2011]染色 树链剖分
来源:互联网 发布:电影魔方软件 编辑:程序博客网 时间:2024/05/23 02:04
题目传送门
这题嘛,第一眼就是树链剖分的裸题,但是我只会用二进制记录颜色数量……看到这题的颜色范围就傻了……(呆.jpg)
因为这题
在询问的时候,还要考虑一下重链顶端和它的父亲的颜色是否相同。
那么这样线段树的处理就非常明朗了,但是这题有一个问题——在修改的时候也要push的。我在这里WA了好几发……(话说我是从什么时候开始养成修改时不push的坏习惯的?)
忍不住吐槽:这题的码量好大啊……好难调试啊……手都敲累了……
附上AC代码:
#include <cstdio>#include <cctype>#include <algorithm>using namespace std;const int N=1e5+10;struct tree{ int cl,cr,sum,lz;}t[N<<2];struct side{ int to,nt;}s[N<<1];int n,m,h[N],num,a[N];int d[N],f[N],sz[N],hs[N],top[N],wz[N],size,rl[N];inline char nc(void){ static char ch[100010],*p1=ch,*p2=ch; return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;}inline void read(int &a){ static char c=nc();int f=1; for (;!isdigit(c);c=nc()) if (c=='-') f=-1; for (a=0;isdigit(c);a=(a<<3)+(a<<1)+c-'0',c=nc()); return (void)(a*=f);}inline void add(int x,int y){ s[++num]=(side){y,h[x]},h[x]=num; s[++num]=(side){x,h[y]},h[y]=num;}inline void so1(int x,int fa){ d[x]=d[f[x]=fa]+1,sz[x]=1; for (int i=h[x]; i; i=s[i].nt) if (s[i].to!=fa){ so1(s[i].to,x); sz[x]+=sz[s[i].to]; if (sz[s[i].to]>sz[hs[x]]) hs[x]=s[i].to; } return;}inline void so2(int x,int fa){ top[x]=fa,wz[x]=++size,rl[size]=x; if (hs[x]) so2(hs[x],fa); else return; for (int i=h[x]; i; i=s[i].nt) if (s[i].to!=f[x]&&s[i].to!=hs[x]) so2(s[i].to,s[i].to); return;}#define lt (k<<1)#define rt (k<<1|1)#define mid ((l+r)>>1)inline void updata(int k){ t[k].cl=t[lt].cl,t[k].cr=t[rt].cr; t[k].sum=t[lt].sum+t[rt].sum-(t[lt].cr==t[rt].cl);}inline void push(int k){ t[lt].cl=t[lt].cr=t[lt].lz=t[k].lz,t[lt].sum=1; t[rt].cl=t[rt].cr=t[rt].lz=t[k].lz,t[rt].sum=1; return (void)(t[k].lz=-1);}inline void build(int k,int l,int r){ t[k].lz=-1; if (l==r) return (void)(t[k].cl=t[k].cr=a[rl[l]],t[k].sum=1); build(lt,l,mid),build(rt,mid+1,r); return updata(k);}inline void change(int k,int l,int r,int ql,int qr,int w){ if (l>=ql&&r<=qr) return (void)(t[k].cl=t[k].cr=t[k].lz=w,t[k].sum=1); if (t[k].lz!=-1) push(k); if (ql<=mid) change(lt,l,mid,ql,qr,w); if (qr>mid) change(rt,mid+1,r,ql,qr,w); return updata(k);}inline void updata(int x,int y,int w){ for (int fx=top[x],fy=top[y]; fx!=fy; x=f[fx],fx=top[x]){ if (d[fx]<d[fy]) swap(x,y),swap(fx,fy); change(1,1,n,wz[fx],wz[x],w); } if (d[x]>d[y]) swap(x,y); return change(1,1,n,wz[x],wz[y],w);}inline tree query(int k,int l,int r,int ql,int qr){ if (l>=ql&&r<=qr) return t[k]; if (t[k].lz!=-1) push(k); tree now={0},tmp={0}; bool bo=0; if (ql<=mid) now=query(lt,l,mid,ql,qr),bo=1; if (qr>mid) if (!bo) now=query(rt,mid+1,r,ql,qr); else{ tmp=query(rt,mid+1,r,ql,qr); now.sum+=tmp.sum-(now.cr==tmp.cl),now.cr=tmp.cr; } return now;}inline int ask(int x,int y){ int ret=0,pre1=-1,pre2=-1;tree tmp; for (int fx=top[x],fy=top[y]; fx!=fy; x=f[fx],fx=top[x]){ if (d[fx]<d[fy]) swap(x,y),swap(fx,fy),swap(pre1,pre2); tmp=query(1,1,n,wz[fx],wz[x]),ret+=tmp.sum-(pre1==tmp.cr),pre1=tmp.cl; } if (d[x]>d[y]) swap(x,y),swap(pre1,pre2); tmp=query(1,1,n,wz[x],wz[y]); return ret+tmp.sum-(tmp.cl==pre1)-(tmp.cr==pre2);}int main(void){ read(n),read(m); for (int i=1; i<=n; ++i) read(a[i]); for (int i=1,x,y; i<n; ++i,read(x),read(y),add(x,y)); so1(1,0),so2(1,1),build(1,1,n); while (m--){ char c=nc();while (c!='C'&&c!='Q') c=nc(); int x,y,w;read(x),read(y); if (c=='C') read(w),updata(x,y,w); else printf("%d\n",ask(x,y)); } return 0;}
阅读全文
0 0
- 【BZOJ】2243 [SDOI2011]染色 树链剖分
- BZOJ 2243 SDOI2011 染色 树链剖分
- BZOJ 2243 [SDOI2011] 染色 (树链剖分)
- BZOJ 2243: [SDOI2011]染色 【树链剖分】
- BZOJ-2243: [SDOI2011]染色-树链剖分
- BZOJ 2243: [SDOI2011]染色 树链剖分
- BZOJ 2243: [SDOI2011]染色 树链剖分
- 【BZOJ】2243 [SDOI2011]染色 树链剖分
- bzoj 2243:[SDOI2011]染色 树链剖分
- 【BZOJ - 2243】 SDOI2011 染色
- BZOJ 2243: [SDOI2011]染色
- 【BZOJ 2243】 [SDOI2011]染色
- bzoj 2243: [SDOI2011]染色
- bzoj 2243: [SDOI2011]染色
- 【BZOJ 2243】[SDOI2011]染色
- BZOJ 2243 [SDOI2011] 染色
- bzoj 2243: [SDOI2011]染色
- BZOJ 2243: [SDOI2011]染色
- 深度学习总结(二)——激活函数的介绍
- 文件系统共享——smb服务
- VUE 关于理解$nextTick()的问题
- 网站页面中常用到的动画
- Linux 进程控制编程
- 【BZOJ】2243 [SDOI2011]染色 树链剖分
- C语言知识小结(四)
- java开发中的23中设计模式(转)
- 【Scikit-Learn 中文文档】使用 scikit-learn 介绍机器学习
- 基于OpenCV的视频图像组态 (6): 形状动画效果
- 模拟实现C++中的Vector函数
- 导航栏渐变方案收录一
- Rxlifecycle使用详解,解决RxJava内存泄露问题
- IE兼容RGBa