hdu 5039 线段树+dfs序
http://acm.hdu.edu.cn/showproblem.php?pid=5039
给定一棵树,边权为0/1。m个操作支持翻转一条边的权值或者询问树上有多少条路径的边权和为奇数。
用树形dfs出每个点到根的路径上边权和是否为奇数;
由于翻转一个边只会连带影响其下的子节点,所有线段树记录更新区间,odd记录到根的路径上边权和为奇数的个数,每次只需更新和查询odd,没有lazy会超时
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
typedef long long LL;
#define L(x) (x<<1)
#define R(x) ((x<<1)|1)
#define MI(x,y) ((x+y)>>1)
const int maxn = 30010;
int head[maxn],l[maxn],r[maxn],val[maxn];
int n,m,tot,idx;
struct edge{
int u,v,f,next;
}ed[maxn<<1];
map<string , int> hash;
struct tree{
int l,r,odd,// odd为到根的路径上边权和为奇数的个数
lazy;// lazy控制翻转次数,翻转偶数次相当于没有翻转
}d[maxn<<2];
void add(int u,int v,int f)
{
ed[tot] = (edge){u,v,f,head[u]},head[u] = tot++;
ed[tot] = (edge){v,u,f,head[v]},head[v] = tot++;
}
void dfs(int u,int f,int fa)
{
idx++;
val[idx] = f;
l[u] = idx;
for(int i = head[u];i != -1;i = ed[i].next){
if(ed[i].v != fa){
dfs(ed[i].v,f ^ ed[i].f,u);
}
}
r[u] = idx;
}
void up(int root)
{
d[root].odd = d[L(root)].odd + d[R(root)].odd;
}
void build(int l,int r,int root)
{
d[root] = (tree){l,r,val[l],0};
if(l == r)
return ;
int mid = MI(l,r);
build(l,mid,L(root));
build(mid+1,r,R(root));
up(root);
}
void down(int root) {
if (d[root].lazy) {
d[L(root)].lazy ^= 1;// 翻转偶数次相当于没翻转,所以不需要更新其子节点
d[R(root)].lazy ^= 1;
d[L(root)].odd = d[L(root)].r - d[L(root)].l + 1 - d[L(root)].odd;
d[R(root)].odd = d[R(root)].r - d[R(root)].l + 1 - d[R(root)].odd;
d[root].lazy = 0;
}
}
void update(int l, int r, int root)
{
if (d[root].l == l && d[root].r == r) {
d[root].odd = d[root].r - d[root].l + 1 - d[root].odd;
d[root].lazy ^= 1;
return;
}
down(root);
int mid = MI(d[root].l,d[root].r);
if (r <= mid)
update(l, r, L(root));
else if (l > mid)
update(l, r, R(root));
else {
update(l, mid, L(root));
update(mid + 1, r, R(root));
}
up(root);
} int main()
{
int _;
RD(_);
string str,rts;
char q[2];
for(int cas = 1;cas <= _;++cas){
printf("Case #%d:\n", cas);
hash.clear();
RD(n);
for(int i = 1;i <= n;++i){
cin>>str;
hash[str] = i;
head[i] = -1;
}
tot = 0;
int u,v,f;
for(int i = 1;i < n;++i){
cin>>str>>rts;
RD(f);
add(hash[str],hash[rts],f);
}
idx = 0;
dfs(1,0,0);
build(1,n,1);
RD(m);
while(m--){
scanf("%s",q);
if(q[0] == 'Q'){
printf("%d\n",d[1].odd * (n - d[1].odd) * 2);
}else{
RD(f);
f = (f-1)<<1;// 边的记录用例两单位的ed
u = ed[f].u,v = ed[f].v;
if(l[u] > l[v])
update(l[u],r[u],1);
else
update(l[v],r[v],1);
}
}
}
return 0;
}
hdu 5039 线段树+dfs序的更多相关文章
- S - Query on a tree HDU - 3804 线段树+dfs序
S - Query on a tree HDU - 3804 离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...
- HDU 5692 线段树+dfs序
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序
题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s 内存限制:512.0MB 总提交次数:196 AC次数:65 平均分: ...
- BZOJ_3252_攻略_线段树+dfs序
BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...
- 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序
题目大意 Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...
- 【bzoj4817】树点涂色 LCT+线段树+dfs序
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数
R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...
- 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序
3779: 重组病毒 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 224 Solved: 95[Submit][Status][Discuss] ...
- 【BZOJ-3306】树 线段树 + DFS序
3306: 树 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 792 Solved: 262[Submit][Status][Discuss] De ...
随机推荐
- git基本命令之删除撤销操作
1.将删除文件恢复--撤销所删除的文件git checkout 文件名 2.git resetgit reset --hard commitID(或某个节点)----强制切换到某个点,会导致所修改的内 ...
- python 解析 yaml文件
import yaml with open("./test.yaml") as f: x = yaml.load(f) print(x) [{'tasks': [{'yum': { ...
- 亲, 我们来再重申一遍"=="和"equals的区别
今天经历的一个事情太丢脸了, 一个学弟向我请教问题, 是这样的: 一个字符串里面含有空格, 不允许使用.trim()和replace方法, 只用if和for将空格去掉, 题目很简单, 一开始我是这样写 ...
- ccf认证模拟题之三---最大的矩形
问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ i ≤ n)个矩形的高度是hi.这n个矩形构成了一个直方图.例如,下图中六个矩形的高度就分别是3, 1, 6, 5, 2, 3 ...
- 网络基础相关的知识 socket模块
1.架构 1.C/S架构:client客户端和server服务器端 优势:能充分发挥pc机的性能 2.B/S架构:browser浏览器和server服务器 隶属于C/S架构 B/S架构 统一了 ...
- 关于Python的OSError和IOError
参考:http://stackoverflow.com/questions/29347790/difference-between-ioerror-and-oserror 在3.x版本已经移除,剩下O ...
- struts框架之总结OGNL表达式的特殊的符号
1. # 符号的用法 * 获得contextMap中的数据 > <s:property value="#request.name"/> > <s:pr ...
- DNA甲基化检测服务
DNA甲基化检测服务 DNA甲基化是最早发现的基因表观修饰方式之一,真核生物中的甲基化仅发生于胞嘧啶,即在DNA甲基化转移酶(DNMTs)的作用下使CpG二核苷酸5'-端的胞嘧啶转变为5'-甲基胞嘧啶 ...
- OSGi 系列(十三)之 Configuration Admin Service
OSGi 系列(十三)之 Configuration Admin Service OSGi 的 CM 就是 Configuration Admin Service,是用于管理 Bundle 属性.并在 ...
- OSGi 系列(一)之什么是 OSGi :Java 语言的动态模块系统
OSGi 系列(一)之什么是 OSGi :Java 语言的动态模块系统 OSGi 的核心:模块化.动态.基于 OSGi 就可以模块化的开发 java 应用,模块化的部署 java 应用,还可以动态管理 ...