题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1、把某结点以及其各个祖先值设为0、询问某结点的值。

对于第一个操作就是经典的DFS序+线段树了。而对于第二个操作,考虑再维护一个域表示各个结点为根的子树是否有进行第二个操作,如果有那么该结点应该就要是0;而在进行第一个操作前,看一下子树是否有进行第二个操作,如果有就整个标记成没有并把标记上传,让该结点的父亲结点标记成进行了第二个操作。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 555555 struct Edge{
int v,next;
}edge[MAXN<<];
int NE,head[MAXN];
void addEdge(int u,int v){
edge[NE].v=v; edge[NE].next=head[u];
head[u]=NE++;
} int l[MAXN],r[MAXN],par[MAXN],dfn;
void dfs(int u,int fa){
l[u]=++dfn;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(v==fa) continue;
par[v]=u;
dfs(v,u);
}
r[u]=dfn;
} int x,y,z,N;
bool tree[MAXN<<],down[MAXN<<],up[MAXN<<];
void updateUp(int i,int j,int k){
if(x<=i && j<=y){
up[k]=z;
return;
}
if(up[k]==){
up[k<<]=;
up[k<<|]=;
}
int mid=i+j>>;
if(x<=mid) updateUp(i,mid,k<<);
if(y>mid) updateUp(mid+,j,k<<|);
up[k]=up[k<<]|up[k<<|];
}
bool queryUp(int i,int j,int k){
if(x<=i && j<=y){
return up[k];
}
if(up[k]==){
up[k<<]=;
up[k<<|]=;
}
int mid=i+j>>; bool res=;
if(x<=mid) res|=queryUp(i,mid,k<<);
if(y>mid) res|=queryUp(mid+,j,k<<|);
return res;
} void update(int i,int j,int k){
if(x<=i && j<=y){
tree[k]=z;
down[k]=z;
return;
}
if(down[k]==){
tree[k<<]=;
tree[k<<|]=;
down[k<<]=;
down[k<<|]=;
down[k]=;
}
int mid=i+j>>;
if(x<=mid) update(i,mid,k<<);
if(y>mid) update(mid+,j,k<<|);
}
bool query(int i,int j,int k){
if(i==j){
return tree[k];
}
if(down[k]==){
tree[k<<]=;
tree[k<<|]=;
down[k<<]=;
down[k<<|]=;
down[k]=;
}
int mid=i+j>>;
if(x<=mid) return query(i,mid,k<<);
else query(mid+,j,k<<|);
} int main(){
int n,q,a,b;
scanf("%d",&n);
memset(head,-,sizeof(head));
for(int i=; i<n; ++i){
scanf("%d%d",&a,&b);
addEdge(a,b);
addEdge(b,a);
} for(N=; N<n; N<<=);
dfs(,); scanf("%d",&q);
while(q--){
scanf("%d%d",&a,&b);
if(a==){
x=l[b]; y=r[b];
if(queryUp(,N,)){
z=;
updateUp(,N,);
if(b!=){
x=l[par[b]]; y=l[par[b]]; z=;
updateUp(,N,);
}
}
x=l[b]; y=r[b]; z=;
update(,N,);
}else if(a==){
x=l[b]; y=l[b]; z=;
updateUp(,N,);
}else if(a==){
x=l[b]; y=r[b];
if(queryUp(,N,)){
puts("");
}else{
x=l[b]; y=l[b];
printf("%d\n",query(,N,));
}
}
}
return ;
}

最新文章

  1. ApiController使用Session验证出现Null解决方案
  2. 浅谈ARP协议以及应用
  3. SQLServer如何用T—SQL命令查询一个数据库中有哪些表
  4. Java [leetcode 2] Add Two Numbers
  5. bash shell学习-shell script基础 (笔记)
  6. Oracle backgroup processes
  7. 使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)
  8. eclipse和myeclipse设置默认编码格式为UTF-8
  9. java8版本base64加密解密
  10. Linux下查看进程打开的文件句柄数
  11. 吴恩达机器学习笔记58-协同过滤算法(Collaborative Filtering Algorithm)
  12. Cnblogs美化总结
  13. 使用diff或者vimdiff比较远程文件(夹)与本地文件夹
  14. Python_动态参数、名称空间、作用域、作用域链、加载顺序、函数的嵌套、global、nonlocal
  15. SpringBoot 4.SpringBoot 整合 devtools 实现热部署
  16. python六十一课——高阶函数之reduce
  17. 洛谷P1099 树网的核
  18. js中如何把字符串转化为对象、数组示例代码
  19. python记录_day08
  20. Java基础知识_毕向东_Java基础视频教程笔记(13 字符)

热门文章

  1. September 19th 2016 Week 39th Monday
  2. ubuntu 添加环境变量
  3. NYOJ题目74小学生算术
  4. const和#define 区别
  5. 有关Oracle数据库
  6. 资源监控工具--spotlight
  7. Python中判断是否为闰年,求输入日期是该年第几天
  8. C/C++学习笔记---高地址、低地址、大段字节序、小段字节序
  9. 【JAVA集合框架之List与Set】
  10. 在MAVEN仓库中添加ORACLE JDBC驱动