线段树+位运算

首先对树进行DFS,写出DFS序列,记录下每一个节点控制的区间范围。然后就是区间更新和区间查询了。

某段区间的颜色种类可以用位运算来表示,方便计算。

如果仅有第i种颜色,那么就用十进制数(1<<i)表示。

如果A区间有的颜色是col1,B区间有的颜色是col2,合并之后有的就是(col1 | col2)

输出有几种,就是看得到的十进制数的二进制表示中有多少位是1.

#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std; const int maxn=*+;
int n,q;
int col[maxn];
vector<int> Tree[maxn];
bool b[maxn];
int Left[maxn],Right[maxn];
int s[*maxn];
int time;
long long ans;
struct SegTree
{
bool flag;
long long ans;
}segTree[*maxn*]; void dfs(int now)
{
b[now]=;
Left[now]=(++time);
s[time]=now;
for(int i=;i<Tree[now].size();i++)
if(b[Tree[now][i]]==)
dfs(Tree[now][i]);
Right[now]=(++time);
s[time]=now;
} void pushUp(int rt)
{
segTree[rt].ans=(segTree[*rt].ans|segTree[*rt+].ans);
} void pushDown(int rt)
{
if(segTree[rt].flag!=)
{
segTree[*rt].flag=segTree[*rt+].flag=segTree[rt].flag;
segTree[*rt].ans=segTree[*rt+].ans=segTree[rt].ans;
segTree[rt].flag=;
}
} void build(int l,int r,int rt)
{
if(l==r)
{
segTree[rt].flag=;
segTree[rt].ans=(long long)<<((long long)col[s[l]]);
return ;
}
int m=(l+r)/;
if(l<=m) build(l,m,*rt);
if(r>m) build(m+,r,*rt+);
pushUp(rt);
return;
} void quary(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
ans=(ans|segTree[rt].ans);
return;
}
pushDown(rt);
int m=(l+r)/;
if(L<=m) quary(L,R,l,m,*rt);
if(R>m) quary(L,R,m+,r,*rt+);
pushUp(rt);
return;
} void update(int info,int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
segTree[rt].flag=info;
segTree[rt].ans=(long long)<<(long long) info;
return;
} pushDown(rt);
int m=(l+r)/;
if(L<=m) update(info,L,R,l,m,*rt);
if(R>m) update(info,L,R,m+,r,*rt+);
pushUp(rt);
} int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++) scanf("%d",&col[i]);
for(int i=;i<=n;i++) Tree[i].clear();
for(int i=;i<=n-;i++)
{
int x,y;
scanf("%d%d",&x,&y);
Tree[x].push_back(y);
Tree[y].push_back(x);
}
memset(b,,sizeof b);
time=,dfs();
build(,*n,);
for(int i=;i<=q;i++)
{
int tk;
scanf("%d",&tk);
if(tk==)
{
int vk,ck;
scanf("%d%d",&vk,&ck);
update(ck,Left[vk],Right[vk],,*n,);
}
else
{
int vk;
scanf("%d",&vk);
ans=;
quary(Left[vk],Right[vk],,*n,);
int num=;
while(ans)
{
if(ans%==) num++;
ans=ans/;
}
printf("%d\n",num);
}
}
return ;
}

CodeForces 620E New Year Tree的更多相关文章

  1. Codeforces 620E New Year Tree(DFS序 + 线段树)

    题目大概说给一棵树,树上结点都有颜色(1到60),进行下面两个操作:把某结点为根的子树染成某一颜色.询问某结点为根的子树有多少种颜色. 子树,显然DFS序,把子树结点映射到连续的区间.而注意到颜色60 ...

  2. CodeForces 620E New Year Tree(线段树的骚操作第二弹)

    The New Year holidays are over, but Resha doesn't want to throw away the New Year tree. He invited h ...

  3. CodeForces 620E:New Year Tree(dfs序+线段树)

    E. New Year Treetime limit per test3 secondsmemory limit per test256 megabytesinputstandard inputout ...

  4. Codeforces 620E New Year Tree(线段树+位运算)

    题目链接 New Year Tree 考虑到$ck <= 60$,那么用位运算统计颜色种数 对于每个点,重新标号并算出他对应的进和出的时间,然后区间更新+查询. 用线段树来维护. #includ ...

  5. codeforces 620E. New Year Tree dfs序+线段树+bitset

    题目链接 给一棵树, 每个节点有颜色, 两种操作, 一种是将一个节点的子树全都染色成c, 一种是查询一个节点的子树有多少个不同的颜色, c<=60. 每个节点一个bitset维护就可以. #in ...

  6. Codeforces 620E New Year Tree【线段树傻逼题】

    LINK 题目大意 给你一棵树 让你支持子树染色,子树查询颜色个数,颜色数<=60, 节点数<=4e5 思路 因为颜色数很少,考虑状态压缩变成二进制 然后直接在dfs序上用线段树维护就可以 ...

  7. CodeForces 620E"New Year Tree"(DFS序+线段树+状态压缩)

    传送门 •题意 给你一颗 n 个节点的树,每个节点被染上了颜色: 有 m 次操作,每次操作的类型有两种 1 v c : 将以 v 为根的子树的结点全部涂成 c 2 v : 询问以 v 为根的子树的结点 ...

  8. Z - New Year Tree CodeForces - 620E 线段树 区间种类 bitset

    Z - New Year Tree CodeForces - 620E 这个题目还没有写,先想想思路,我觉得这个题目应该可以用bitset, 首先这个肯定是用dfs序把这个树转化成线段树,也就是二叉树 ...

  9. Codeforces 461B Appleman and Tree(木dp)

    题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...

随机推荐

  1. ccw-ide

    有bug,会把working set弄乱,整理后能重启一次正常,再次重启又乱了.

  2. ASP:GB2312格式文本文件转换成UTF-8格式

    '-------------------------------------------------'函数名称:gb2utf_file'作用:利用AdoDb.Stream对象来把GB2312格式文本文 ...

  3. 源码篇:SDWebImage

    攀登,一步一个脚印,方能知其乐 源码篇:SDWebImage 源码来源:https://github.com/rs/SDWebImage 版本: 3.7 SDWebImage是一个开源的第三方库,它提 ...

  4. Mysql转化blob为可读

    -- info 为列名 SELECT convert(info using latin1) FROM drupal755.system; SELECT convert(info using utf8) ...

  5. Automatic Trading

    Automatic Trading A brokerage firm is interested in detecting automatic trading. They believe that a ...

  6. OpenGL--------纹理处理

    我们可以将像素数据按照矩形进行缩小和放大,但是还不足以满足我们的要求.例如要将一幅世界地图绘制到一个球体表面,只使用glPixelZoom这样的函数来进行缩放显然是不够的.OpenGL纹理映射功能支持 ...

  7. HDU 2668 Daydream

    用一个队列来维护 每次加入一个字符,如果字符没有在队列里,那么直接入队,并且检查更新队列大小. 如果加入的字符在队列里了,那么要一直弹出队首,直到弹出的字符和当前要插入的一样. #include< ...

  8. EL表达式,保留小数点后两位

    你遇到过页面显示小数有9.987870488E9这个吗? 这是因为没有保留小数的原因 有时候用js保留小数很麻烦的时候,可以用EL表达式 <fmt:formatNumber type=" ...

  9. apache禁止公网IP访问的配置

    由于最近在配置负载均衡环境 外网使用Nginx做代理,分发到Apache服务器上,所以不希望Apache配置的服务被外网访问,只希望内网Nginx访问,所以只能使用局域网IP访问 配置方法: 打开Ap ...

  10. 区间的关系的计数 HDU 4638 离线+树状数组

    题目大意:给你n个人,每个人都有一个id,有m个询问,每次询问一个区间[l,r],问该区间内部有多少的id是连续的(单独的也算是一个) 思路:做了那么多离线+树状数组的题目,感觉这种东西就是一个模板了 ...