cf-edu#6- E - New Year Tree -dfs序+线段树维护
2016-01-22 16:50
375 查看
http://codeforces.com/contest/620/problem/E
C《60,n<=1e5
题意:给你n个节点的 无向有根树
给你每个节点的初始颜色ci
q次操作
操作1:1 v k 把v节点的所有子节点颜色都换成k
操作2:2 v 查询v节点的所有子节点颜色种类
先dfs跑一遍得到 一个dfs序
把每个节点涂上初始颜色, 每个节点在dfs序中的位置是in[i], 也就是update(in[i],val);
这个颜色只有60种,我们用一个int64变量来表示即可
那么每次操作1 ,我们就update线段树的【 in[i],out[i]】区间为 值 1<<(kind-1);
每次操作2 ,就查询【 in[i],out[i]】的和
维护颜色种类的时候直接用|操作非常方便, 维护的一个值x,其二进制下1的个数代表其管辖区间的颜色种类
C《60,n<=1e5
题意:给你n个节点的 无向有根树
给你每个节点的初始颜色ci
q次操作
操作1:1 v k 把v节点的所有子节点颜色都换成k
操作2:2 v 查询v节点的所有子节点颜色种类
先dfs跑一遍得到 一个dfs序
把每个节点涂上初始颜色, 每个节点在dfs序中的位置是in[i], 也就是update(in[i],val);
这个颜色只有60种,我们用一个int64变量来表示即可
那么每次操作1 ,我们就update线段树的【 in[i],out[i]】区间为 值 1<<(kind-1);
每次操作2 ,就查询【 in[i],out[i]】的和
维护颜色种类的时候直接用|操作非常方便, 维护的一个值x,其二进制下1的个数代表其管辖区间的颜色种类
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <set> #include <stack> #include <iostream> using namespace std; __int64 inf=15; double eps=0.000001; const __int64 N=4*100000+5; vector < vector<__int64> > mp(N); __int64 id; __int64 in ,out ; __int64 vis ; void dfs1(__int64 x) { in[x]=++id; vis[x]=1; __int64 i; for (i=0;i<mp[x].size();i++) { __int64 v=mp[x][i]; if (vis[v]) continue; dfs1(v); } out[x]=id; } __int64 add[N*4]; __int64 sum[N*4]; void pushDown(__int64 i,__int64 l,__int64 r) { if (add[i]) { __int64 mid=(l+r)>>1; add[i<<1]=add[i]; sum[i<<1]=add[i]; add[i<<1|1]=add[i]; sum[i<<1|1]=add[i]; add[i]=0; } } void update(__int64 i,__int64 l ,__int64 r,__int64 ql,__int64 qr,__int64 val) { if (l>qr||r<ql) return ; if (l>=ql&&r<=qr) { sum[i]=val; add[i]=val; return ; } pushDown(i,l,r); __int64 mid=(l+r)>>1; update(i<<1,l,mid,ql,qr,val); update(i<<1|1,mid+1,r,ql,qr,val); sum[i]=sum[i<<1]|sum[i<<1|1]; } __int64 query(__int64 i,__int64 l,__int64 r,__int64 ql,__int64 qr ) { if (l>qr||r<ql) return 0; if (l>=ql&&r<=qr) return sum[i]; pushDown(i,l,r); __int64 mid=(l+r)>>1; __int64 ret1=query(i<<1,l,mid,ql,qr); __int64 ret2=query(i<<1|1,mid+1,r,ql,qr); return ret1|ret2; } __int64 cc ; int main() { __int64 one=1; __int64 x,y,i; int n,q; cin>>n>>q; id=0; for (i=1;i<=n;i++) scanf("%I64d",&cc[i]); for (i=1;i<=n-1;i++) { scanf("%I64d%I64d",&x,&y); mp[x].push_back(y); mp[y].push_back(x); } dfs1(1); for (i=1;i<=n;i++) { __int64 xx=one<<(cc[i]-1); update(1,1,n,in[i],in[i],xx); } __int64 op,vv,kk; for (i=1;i<=q;i++) { scanf("%I64d",&op); if (op==1) { scanf("%I64d%I64d",&vv,&kk); __int64 xx=one<<(kk-1); update(1,1,n,in[vv],out[vv],xx); } else { scanf("%I64d",&vv); __int64 ans=query(1,1,n,in[vv],out[vv]); __int64 cun=0; while(ans) { cun+=ans%2; ans>>=1; } printf("%I64d\n",cun); } } return 0; }
相关文章推荐
- 在opencv3中的机器学习算法练习题:对OCR进行分类
- openfire服务器无法开启问题
- 分布式网站部署
- 线上bug的解决方案--带来的全新架构设计
- yum rpm 命令 linux
- ETL 运行维护
- .net mvc DropDownListFor下拉列表使用(验证)方法
- LINUX下目标文件的BSS段、数据段、代码段
- 基于LINUX的多媒体框架Gstreamer开发与使用
- Linux字符设备驱动和杂项设备驱动对比
- linux 常用命令
- Shell -------- 检测utf-8 是否 带bomb
- VS2010旗舰版+OpenCV2.2.0配置过程及测试程序
- CentOS安装Node.js
- 遇到shell重定向的一个奇怪问题:'消失'的标准输入!
- CentOS使用mkfs.ext4快速格式化大容量硬盘
- Ubuntu 为 root 帐号开启 SSH 登录
- Linux 目录结构
- (总结)Linux的chattr与lsattr命令详解
- Pinterest月PV百亿的架构设计