CF--- PROBLEM 620 E 【思维 + DFS序 + 二进制状态】
来源:互联网 发布:中国保险保险网络大学 编辑:程序博客网 时间:2024/06/05 21:49
传送门
//题意: 对于一棵树以1为根的树, 每个结点有一种颜色. 现在有两种操作.
1 x y 把以x为根节点的子树中的所有节点染成颜色y
2 x 询问以x为根节点的子树中有多少种颜色的节点
//思路: 很明显的DFS序, 需要考虑几点, 涉及到线段树的区间修改. 然后就是颜色的计数, 由于颜色最多60种, 那么用long long 的二进制来表示它的颜色. 这样再pushup时直接左右子树或起来就行. 注意一个坑点就是在DFS序中的线段树描述的是各个节点的序了!!! 不再是每一个节点本身. 所以在build中, tree[id].val = a[dfsxu[l]] (dfsxu表示的是当前节点在dfs序中代表的节点!!!), 而不是a[l] !!! 这个BUG调了我好久. 要多做做这方面的题啊.
AC Code
/** @Cain*/const int maxn = 4e5+5;int cas=1;ll a[maxn];int dfs_xx[maxn];struct node{ int tl, tr; ll val, maxx, lazy; void fun(ll tmp) { //如果是直接加值就用 += lazy = tmp; val = 1ll<<(tmp-1); //maxx = tmp; }} tree[maxn*4];void pushup(int id){ tree[id].val = tree[id<<1].val|tree[id<<1|1].val; //tree[id].maxx = max(tree[id<<1].maxx,tree[id<<1|1].maxx);}void pushdown(int id){ if(tree[id].lazy){ tree[id<<1].fun(tree[id].lazy); tree[id<<1|1].fun(tree[id].lazy); tree[id].lazy = 0; }}void build(int id,int l,int r){ tree[id].tl = l; tree[id].tr = r; tree[id].lazy = 0; if(l == r){ tree[id].val = a[dfs_xx[l]]; //这是一个坑点啊.就如上面我所说. return ; } int mid = (l+r) >> 1; build(id<<1,l,mid); build(id<<1|1,mid+1,r); pushup(id);}void update(int id,int st,int ed,int val){ int l=tree[id].tl, r=tree[id].tr; if(st <= l && r <= ed){ tree[id].fun(val); return ; } pushdown(id); int mid = (l+r) >> 1; if(st <= mid) update(id<<1,st,ed,val); if(ed > mid) update(id<<1|1,st,ed,val); pushup(id);}ll query(int id,int ql,int qr){ int l = tree[id].tl , r = tree[id].tr; if(ql <= l && r <= qr) return tree[id].val; pushdown(id); int mid = (l+r) >> 1 ; ll res = 0; if(ql <= mid) res |= query(id<<1,ql,qr); if(qr > mid) res |= query(id<<1|1,ql,qr); return res;}struct edge{ int to,next; ll w;}s[maxn];int cnt,ti,head[maxn];int p1[maxn],p2[maxn];void add(int u,int v,ll w){ s[cnt] = (edge){v,head[u],w}; head[u] = cnt++;}void dfs_id(int u,int fa){ p1[u] = ++ti; dfs_xx[ti] = u; for(int i=head[u]; ~i ; i = s[i].next){ int to = s[i].to; if(fa == to) continue; dfs_id(to,u); } p2[u] = ti;}void solve(){ int n,q; ll b[50]; scanf("%d%d",&n,&q); for(int i=1;i<=n;i++){ ll u; scanf("%lld",&u); b[i] = u; a[i] = 1ll<<(u-1); } ti = cnt = 0; Fill(head,-1); for(int i=1;i<=n-1;i++){ int u,v; scanf("%d%d",&u,&v); add(u,v,1); add(v,u,1); } dfs_id(1,-1); build(1,1,n); while(q--){ int op; scanf("%d",&op); if(op == 1) { int u,v; scanf("%d%d",&u,&v); update(1,p1[u],p2[u],v); } else { int u; scanf("%d",&u); ll x = query(1,p1[u],p2[u]); int cnt = 0; while(x){ if(x&1) cnt++; x >>= 1; } printf("%d\n",cnt); } }}
阅读全文
0 0
- CF--- PROBLEM 620 E 【思维 + DFS序 + 二进制状态】
- [CF]291E. Tree-String Problem | dfs+kmp
- 【CF 620E 】New Year Tree 【DFS+线段树+状态压缩】
- CF 717E[dfs]
- CF contest 888 problem E 【思维 + 状压 + 中途相遇法(折半搜索)】
- CF problem 166E Tetrahedron
- codeforces 620E New Year Tree (DFS序+线段树区间操作+二进制)
- CF 879 C. Short Program 思维+二进制
- CF 208E Blood Cousins(二分+DFS)
- CF 600E(Lomsat gelral-dfs)
- Graph Cutting CF 405E DFS
- CF#701 E. Connecting Universities (DFS)
- CF 55E Very simple problem 题解
- CF #439 E Another Maximum Problem
- Codeforces 620E New Year Tree dfs序+线段树+状态压缩
- CF 31E 分块,状态压缩
- Codeforces 659E New Reform【思维+Dfs】
- 761E Dasha and Puzzle[dfs][思维]
- anaconda查看、安装、更新库
- Leetcode c语言-Longest Palindromic Substring
- 数据库(5)聚合、分组、排序、分页
- python学习(2)
- petalinux 2017.2安装指南
- CF--- PROBLEM 620 E 【思维 + DFS序 + 二进制状态】
- PHP匿名函数(闭包函数)
- Javaweb中JSP和Servlet的概述
- javascript入门第一课
- 看图说mapreduce的shuffle机制
- 页面底部功能区布局
- HDU 1003最大子段和
- Android高级进阶-换肤
- 数据结构(Java)---线性表