【bzoj2243】[SDOI2011]染色(树链剖分)
来源:互联网 发布:冒险岛2检测数据异常 编辑:程序博客网 时间:2024/05/26 02:20
题目:
我是超链接
这个题要维护左右端点的颜色以及中间的颜色段数
然后能说的只有各个数组的意义了
num[i]真实树中的点i在线段树最底层的编号;tree[i]线段树底层编号为i的点在真树中的编号;woc[i]底层编号为i的点在整棵线段树中的编号
最后要注意的就是数据范围了,deep啥的都是N,线段树中是4N,连边的是2N
代码:#include <cstdio>#include <iostream> #define N 200000#define MIN -1e9using namespace std;int nxt[N*2],point[N*2],v[N*2],tot=0,cnt=0,n;int deep[N],size[N],fa[N],top[N],son[N],tree[N],num[N],totw=0;int sum[N*4],ll[N*4],rr[N*4],delta[N*4],w[N],woc[N*4+5];void addline(int x,int y){++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x;} void updata(int now){sum[now]=sum[now<<1]+sum[now<<1|1];if (rr[now<<1]==ll[now<<1|1]) sum[now]--;ll[now]=ll[now<<1];rr[now]=rr[now<<1|1];}void pushdown(int now){ if (delta[now]){delta[now<<1]=delta[now];delta[now<<1|1]=delta[now];sum[now<<1]=sum[now<<1|1]=1;ll[now<<1]=rr[now<<1]=delta[now];ll[now<<1|1]=rr[now<<1|1]=delta[now];delta[now]=0;}}void dfs_1(int now,int dep,int faa){deep[now]=dep;size[now]=1;fa[now]=faa;int maxx=MIN;for (int i=point[now];i;i=nxt[i]) if (v[i]!=faa) { dfs_1(v[i],dep+1,now); size[now]+=size[v[i]]; if (size[v[i]]>maxx) { maxx=size[v[i]]; son[now]=v[i];} }}void dfs_2(int now,int faa){if (son[faa]!=now) top[now]=now;else top[now]=top[faa];num[now]=++totw;if (son[now]){dfs_2(son[now],now);for (int i=point[now];i;i=nxt[i]) if (v[i]!=son[now] && v[i]!=faa) dfs_2(v[i],now);}}void build(int now,int l,int r){if (l==r){woc[l]=now;sum[now]=1;ll[now]=rr[now]=w[tree[l]];return;}int mid=(l+r)>>1;build(now<<1,l,mid);build(now<<1|1,mid+1,r);updata(now);} void change(int now,int l,int r,int lrange,int rrange,int v){if (l>=lrange && r<=rrange){sum[now]=1;ll[now]=rr[now]=v;delta[now]=v;return;}pushdown(now);int mid=(l+r)>>1;if (mid>=lrange) change(now<<1,l,mid,lrange,rrange,v);if (mid<rrange) change(now<<1|1,mid+1,r,lrange,rrange,v);updata(now);}int qurry(int now,int l,int r,int lrange,int rrange){if (l>=lrange && r<=rrange) return sum[now];pushdown(now);int mid=(l+r)>>1,ans=0;bool qd1,qd2;qd1=false; qd2=false;if (mid>=lrange){ans+=qurry(now<<1,l,mid,lrange,rrange);qd1=true;}if (mid<rrange){ans+=qurry(now<<1|1,mid+1,r,lrange,rrange);qd2=true;}if (qd1 && qd2 && ll[now<<1|1]==rr[now<<1]) ans--;updata(now);return ans;}void work(int u,int v,int c,int id){int f1=top[u],f2=top[v],summ=0;while (f1!=f2) {if (deep[f1]<deep[f2]) {swap(f1,f2); swap(u,v);}if (id==1) change(1,1,n,num[f1],num[u],c); else{summ+=qurry(1,1,n,num[f1],num[u]);int zz=qurry(1,1,n,num[fa[f1]],num[fa[f1]]);zz=qurry(1,1,n,num[f1],num[f1]);if (ll[woc[num[f1]]]==ll[woc[num[fa[f1]]]]) summ--;}u=fa[f1]; f1=top[u];}if (num[u]>num[v]) swap(u,v);if (id==1) change(1,1,n,num[u],num[v],c);else{summ+=qurry(1,1,n,num[u],num[v]);printf("%d\n",summ);}}int main(){int m,i,x,y,u,c,vv;scanf("%d%d",&n,&m);for (i=1;i<=n;i++) scanf("%d",&w[i]);for (i=1;i<=n-1;i++){scanf("%d%d",&x,&y);addline(x,y);}dfs_1(1,1,0);dfs_2(1,0);for (i=1;i<=n;i++) tree[num[i]]=i;build(1,1,n);for (i=1;i<=m;i++){char st[5];scanf("%s",st);if (st[0]=='C'){scanf("%d%d%d",&u,&vv,&c);work(u,vv,c,1);} else{scanf("%d%d",&u,&vv);work(u,vv,0,2);}} }
1 0
- 【bzoj2243】[SDOI2011]染色(树链剖分)
- bzoj2243: [SDOI2011]染色 树链剖分
- 【BZOJ2243】[SDOI2011]染色 树链剖分
- 【BZOJ2243】【SDOI2011】染色 树链剖分
- 【SDOI2011】【BZOJ2243】【树链剖分】染色
- 【bzoj2243】【sdoi2011】染色【树链剖分】
- Bzoj2243[SDOI2011]染色:树链剖分
- [SDOI2011] [BZOJ2243] 染色 - 树链剖分
- BZOJ2243 【SDOI2011】染色 树链剖分
- BZOJ2243: [SDOI2011]染色 树链剖分
- bzoj2243 SDOI2011 染色 树链剖分
- [树链剖分] [bzoj2243] [SDOI2011]染色
- bzoj2243 [SDOI2011]染色 树链剖分
- 【BZOJ2243】【SDOI2011】染色(树链剖分+线段树)
- bzoj2243: [SDOI2011]染色(树链剖分+线段树)
- [BZOJ2243]SDOI2011染色|树链剖分|LCT
- [省选] [树链剖分] [BZOJ2243] [SDOI2011] 染色
- 【bzoj2243】 [SDOI2011]染色 树链剖分+线段树
- The connection to adb is down, and a severe error has occured.
- leetcode_70. Climbing Stairs
- 杂项
- Sql Server2008R2安装时,错误代码0x84B20001
- iOS 动画进阶
- 【bzoj2243】[SDOI2011]染色(树链剖分)
- 大热剧《三生三世十里桃花》凭什么这么火?
- txt中,ANSI 的编码格式为什么可以显示中文?
- 模拟新闻APP显示界面
- Mysql安装步骤
- TortoiseSVN的bin目录下面没有svn.exe
- Centos 7 minimal 防火墙firewall开放端口
- Sublime Text常用命令
- 使用jstl