P2486 [SDOI2011]染色

树链剖分

用区间修改线段树维护

对于颜色段的计算:sum[o]=sum[lc]+sum[rc]

因为可能重复计算,即左子树的右端点和右子树的左端点可能颜色相同

多开2个数组lx,rx记录左/右端点的颜色,重复的话 sum[o]- - 即可

(我的错误模板坑了我2h)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
using namespace std;
template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;}
template <typename T> inline void read(T &x){
char c=getchar(); x=; bool f=;
while(!isdigit(c)) f= !f||c=='-' ? :,c=getchar();
while(isdigit(c)) x=(x<<)+(x<<)+(c^),c=getchar();
x= f ? x:-x;
}
template <typename T> inline void output(T x){
if(!x) {putchar(); return ;}
if(x<) putchar('-'),x=-x;
int wt[],l=;
while(x) wt[++l]=x%,x/=;
while(l) putchar(wt[l--]+);
}
typedef int arr[];
int n,m,cnt,tot;
arr d,fa,siz,bgs,tp,tmp,val,id,hd,ed;
int nxt[],poi[];
int lx[],rx[],sum[],tag[];
inline void add_(int x,int y){
nxt[ed[x]]=++cnt; hd[x]= hd[x] ? hd[x]:cnt;
ed[x]=cnt; poi[cnt]=y;
}
inline void pushdown(int o){
if(tag[o]==-) return ;
int lc=o<<,rc=o<<|;
sum[lc]=sum[rc]=;
lx[lc]=rx[lc]=lx[rc]=rx[rc]=tag[o];
tag[lc]=tag[rc]=tag[o];
tag[o]=-;
}
inline void maintain(int o){
int lc=o<<,rc=o<<|;
lx[o]=lx[lc],rx[o]=rx[rc],sum[o]=sum[lc]+sum[rc];
if(rx[lc]==lx[rc]) --sum[o]; //重复减掉
}
inline void build(int o,int l,int r){
tag[o]=-;
if(l==r) {tag[o]=lx[o]=rx[o]=tmp[l]; sum[o]=; return ;}
int lc=o<<,rc=o<<|,mid=l+((r-l)>>);
build(lc,l,mid); build(rc,mid+,r);
maintain(o);
}
inline void modify(int o,int l,int r,int x1,int x2,int v){
if(x1<=l&&r<=x2){
lx[o]=rx[o]=tag[o]=v; sum[o]=;
return ;
}pushdown(o);
int lc=o<<,rc=o<<|,mid=l+((r-l)>>);
if(x1<=mid) modify(lc,l,mid,x1,x2,v);
if(x2>mid) modify(rc,mid+,r,x1,x2,v);
maintain(o);
}
inline int query(int o,int l,int r,int x1,int x2){
if(x1<=l&&r<=x2) return sum[o];
pushdown(o); int res=;
int lc=o<<,rc=o<<|,mid=l+((r-l)>>);
if(x1<=mid) res+=query(lc,l,mid,x1,x2);
if(x2>mid){
res+=query(rc,mid+,r,x1,x2);
if(x1<=mid&&rx[lc]==lx[rc]) --res;
}return res;
}
inline void dfs1(int x,int _fa){
d[x]=d[_fa]+,fa[x]=_fa,siz[x]=;
for(int i=hd[x];i;i=nxt[i])
if(poi[i]!=_fa){
dfs1(poi[i],x);
siz[x]+=siz[poi[i]];
if(siz[bgs[x]]<siz[poi[i]]) bgs[x]=poi[i];
}
}
inline void dfs2(int x,int _top){
id[x]=++tot,tmp[tot]=val[x],tp[x]=_top;
if(siz[x]==) return;
dfs2(bgs[x],_top);
for(int i=hd[x];i;i=nxt[i])
if(poi[i]!=fa[x]&&poi[i]!=bgs[x])
dfs2(poi[i],poi[i]);
}
inline int findcol(int o,int l,int r,int x){
if(l==r) return tag[o];
pushdown(o);
int lc=o<<,rc=o<<|,mid=l+((r-l)>>);
if(x<=mid) return findcol(lc,l,mid,x);
else return findcol(rc,mid+,r,x);
}
inline void change(int x,int y,int v){
while(tp[x]!=tp[y]){ //™模板原来这里多套了个d数组上去,变成50pts
if(d[tp[x]]<d[tp[y]]) swap(x,y);
modify(,,n,id[tp[x]],id[x],v);
x=fa[tp[x]];
}if(d[x]>d[y]) swap(x,y);
modify(,,n,id[x],id[y],v);
}
inline int ask(int x,int y){
int res=,r1,r2;
while(tp[x]!=tp[y]){
if(d[tp[x]]<d[tp[y]]) swap(x,y);
res+=query(,,n,id[tp[x]],id[x]);
r1=findcol(,,n,id[tp[x]]);
r2=findcol(,,n,id[fa[tp[x]]]);
if(r1==r2) --res;
x=fa[tp[x]];
}if(d[x]>d[y]) swap(x,y);
res+=query(,,n,id[x],id[y]);
return max(res,);
}
int main(){
read(n); read(m); int q1,q2,q3; char opt[];
for(int i=;i<=n;++i) read(val[i]);
for(int i=;i<n;++i) read(q1),read(q2),add_(q1,q2),add_(q2,q1);
dfs1(,); dfs2(,); build(,,n);
for(int i=;i<=m;++i){
scanf("%s",opt); read(q1),read(q2);
if(opt[]=='Q') output(ask(q1,q2)),putchar('\n');
else read(q3),change(q1,q2,q3);
}return ;
}

最新文章

  1. CoolPlist 帧动画自动生成工具
  2. angularjs路由
  3. oracle创建表相关
  4. ios提示框,自动消失
  5. UVa(11292),贪心水题
  6. IPAD2 5.1.1越狱后的屏幕不能自动旋转~~~
  7. c语言数据处理!
  8. HTML5媒体播放说明
  9. 命令行修改linux系统IP
  10. iOS 学习
  11. Flume1.9.0的安装、部署、简单应用(含分布式、与Hadoop3.1.2、Hbase1.4.9的案例)
  12. JS前端无侵入实现防止重复提交请求技术
  13. Flex builder4.6激活【转】
  14. domain
  15. jquery获取select多选框选中的值
  16. Eclipse Creating a New Runnable JAR File 清理工作空间下的配置文件
  17. mongodb中直接根据某个字段更新另外一个字段值
  18. jQuery小案例
  19. 使用WebUploader客户端批量上传图片,后台使用springMVC接收实例
  20. 推荐3个小程序开源组件库——Vant、iView、ColorUI

热门文章

  1. Nginx防止恶意域名解析
  2. 《into100-创客+沙龙第4期:互联网产品用户需求挖掘与转化》圆满成功
  3. Codeforces 349C - Mafia
  4. HDFS Snapshots
  5. 如何在Ubuntu 14.10 上安装WordPress?
  6. nginx之配置proxy_set_header
  7. FCoin API
  8. PL/SQL类的应用
  9. LeetCode-104.Maxinum Depth of Binary Tree
  10. 前端 html input标签 placeholder属性 标签上显示内容