HDU5039--Hilarity DFS序+线段树区间更新 14年北京网络赛
题意:n个点的树,每个条边权值为0或者1, q次操作
Q 路径边权抑或和为1的点对数, (u, v)(v, u)算2个。
M i修改第i条边的权值 如果是0则变成1, 否则变成0
作法: 我们可以求出每个点到根节点路径边权抑或和为val, 那么ans = val等于0的个数乘val等于1的个数再乘2。
注意到每一次修改操作,只会影响以u为根的子树(假设边为u----v dep[v] > dep[u]), 那么每次只需把子树区间的值与1抑或就行了。 这一步可以用线段树区间更新。
比赛时过的人好少。。。好奇怪。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e4 + ;
struct Edge {
int to, cost;
Edge (int to, int cost){
this->to = to, this->cost = cost;
}
};
vector <Edge> G[MAXN];
int val[MAXN];
int siz[MAXN], pt1[MAXN], pt2[MAXN], IDX, dep[MAXN];
void dfs(int u, int father, int k) {
val[u] = k;
dep[u] = dep[father] + ;
pt1[u] = ++IDX;
for (Edge e: G[u]) {
int v = e.to;
if (v != father) {
dfs(v, u, k^e.cost);
}
}
pt2[u] = IDX;
}
int seg[][MAXN << ], lazy[MAXN << ];
void push_down (int pos) {
if (lazy[pos]) {
swap(seg[][pos<<], seg[][pos<<]);
swap(seg[][pos<<|], seg[][pos<<|]);
lazy[pos<<] ^= lazy[pos];
lazy[pos<<|] ^= lazy[pos];
lazy[pos] = ;
}
}
void build (int l, int r, int pos, int x, int d) {
if (l == r) {
seg[][pos] = d == ;
seg[][pos] = d == ;
return;
}
int mid = (l + r) >> ;
if (x <= mid) {
build(l, mid, pos<<, x, d);
} else {
build(mid+, r, pos<<|, x, d);
}
seg[][pos] = seg[][pos<<] + seg[][pos<<|];
seg[][pos] = seg[][pos<<] + seg[][pos<<|];
}
void update (int l, int r, int pos, int ua, int ub) {
if (ua <= l && ub >= r) {
lazy[pos] ^= ;
swap(seg[][pos], seg[][pos]);
return;
}
push_down(pos);
int mid = (l + r) >> ;
if (ua <= mid) {
update(l, mid, pos<<, ua, ub);
}
if (ub > mid) {
update(mid+, r, pos<<|, ua, ub);
}
seg[][pos] = seg[][pos<<] + seg[][pos<<|];
seg[][pos] = seg[][pos<<] + seg[][pos<<|];
}
void init () {
IDX = ;
memset(lazy, , sizeof (lazy));
memset(seg, , sizeof seg);
for (int i = ; i < MAXN; i++) {
G[i].clear();
}
}
pair <int, int> edge[MAXN];
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
int T, cas = ;
scanf ("%d", &T);
while (T--) {
init();
int n, q;
int tot = ;
map <string, int> mp;
scanf ("%d", &n);
for (int i = ; i <= n; i++) {
char buff[];
scanf ("%s", buff);
mp[buff] = ++tot;
}
for (int i = ; i < n-; i++) {
char name1[], name2[];
int status;
scanf ("%s%s%d", name1, name2, &status);
edge[i] = make_pair(mp[name1], mp[name2]);
G[edge[i].first].push_back(Edge(edge[i].second, status));
G[edge[i].second].push_back(Edge(edge[i].first, status));
}
dfs(, , );
build(, IDX, , pt1[], );
for (int i = ; i < n-; i++) {
int u = edge[i].first;
int v = edge[i].second;
if (dep[u] > dep[v]) {
swap(u, v);
}
build(, IDX, , pt1[v], val[v]);
}
scanf ("%d", &q);
printf("Case #%d:\n", cas++);
for (int i = ; i < q; i++) {
char kind[];
scanf ("%s", kind);
if (kind[] == 'Q') {
printf("%d\n", seg[][] * seg[][] * );
} else {
int e;
scanf ("%d", &e);
int u = edge[e-].first;
int v = edge[e-].second;
if (dep[u] > dep[v]) {
swap(u, v);
}
update(, IDX, , pt1[v], pt2[v]);
}
}
}
return ;
}
HDU5039--Hilarity DFS序+线段树区间更新 14年北京网络赛的更多相关文章
- 【DFS序+线段树区间更新区间求最值】HDU 5692 Snacks
http://acm.hdu.edu.cn/showproblem.php?pid=5692 [思路] 每更新一个点,子树的所有结点都要更新,所以是区间更新 每查询一个点,子树的所有结点都要查询,所以 ...
- NBOJv2 1034 Salary Inequity(DFS序+线段树区间更新区间(最值)查询)
Problem 1034: Salary Inequity Time Limits: 10000 MS Memory Limits: 200000 KB 64-bit interger IO ...
- POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...
- HDU5032 -- Always Cook Mushroom 树状数组 14年北京网络赛
题意:1000*1000的格子, 坐标为(1, 1) ~ (1000, 1000), 常数 A, B, 点(x, y)权值为 (x + A) * (y + B), q次询问, 每次询问(0, 0) ...
- 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...
- DFS序+线段树(bzoj 4034)
题目链接 题目就不多说了. 本题目,可以用dfs序+线段树做:题目给定了一棵树,树上节点告诉了权值.我们可以先将这棵树进行dfs将一棵树变成线性结构:如图 变成这样后,然后就可以用线段树. 操作1:也 ...
- 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)
牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
- BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)
题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
随机推荐
- 自定义控件(视图)2期笔记08:自定义控件之 9patch图说明
1. 何为 9patch图 ? 它是一个对png图片做处理的一个工具,能够为我们生成一个"*.9.png"的图片:所谓"*.9.png"这是Androi ...
- Java中Long与long的区别(转)
Java中Long与long的区别(转) [本文转载自:http://www.cnblogs.com/bluestorm/archive/2012/04/22/2464739.html] 转载请联系原 ...
- HTML5之canvas
canvas的创建,canvas图片的绘制及图片的封装,矩形,矩形边框,圆,线的绘制. JavaScript代码如下:main.js /** * Created by zengkm on 15-9-1 ...
- eclise -The method onClick(View) of type new View.OnClickListener(){} must override a superclass method
在做arcgis android开发的时候,突然遇到这种错误,The method onClick(View) of type new View.OnClickListener(){} must ov ...
- 写一个基于NSURLSession的网络下载库
前段时间AFNetworking 更新到3.0 ,彻底废弃NSURLConnection的API转由NSURLSession来实现,代码并没有改动很大,AF封装的很好了,读完源码感觉收获很大. 下载不 ...
- META http-equiv 大全
META http-equiv 大全 HTTP-EQUIV类似于HTTP的头部协议,它回应给浏览器一些有用的信息,以帮助正确和精确地显示网页内容.常用的HTTP-EQUIV类型有: 1.Content ...
- c# sqlserver备份还原(转)
WinForm c# 备份 还原 数据库 其实是个非常简单的问题,一个Form,一个Button,一个OpenFileDialog,一个SaveFileDialog.下面给出备份与还原类 using ...
- jquery ajax(5)form表单序列化
form表单序列化<script type="text/javascript"> $(function(){ $("#send").click(fu ...
- python模块之json序列化
31.序列化: 1.json实现序列化,json.dumps()和json.loads(). >>> s1 = {'k1':'v1','k2':'v2' ...
- SQLServer -- 递归查询树结构表
需求 查询树结构表(如菜单类型表,文件夹类型表等)中一个数据节点下所有的子节点数据 声明临时表,并写入数据如下 DECLARE @tbl TABLE ( Id INT ,ParentId INT ,N ...