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'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
随机推荐
- [转] STL源码学习----lower_bound和upper_bound算法
http://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html PS: lower_bound of value 就是最后一个 < ...
- jsp页面禁用缓存
问题:为什么禁用JSP页面缓存 就是为了得到实时信息 怎样禁用JSP页面缓存 1.在JSP页面设置 <meta http-equiv="pragma" content=&qu ...
- JNI与多线程
在android开发过程中,由于主线程要聚焦于UI交互,为了软件运行流畅必然要用到很多多线程技术.而在JNI机制中专门提供了一些避免线程冲突的函数.了解.学习并掌握如何避免线程冲突问题是一个程序猿的必 ...
- Bernese安装及使用
一.安装: 伯尔尼软件的安装很简单,但是在64位下,可能perl解释器安装不成功,我找了一个,并且可用,下载地址: 链接:http://pan.baidu.com/s/1hr8fgEC 密码:fj8b ...
- okhttp 基本介绍
资料汇总 官网:http://square.github.io/okhttp/ 文档:https://github.com/square/okhttp/wiki GitHub:https://gith ...
- Miller_Rabin codevs 1702 素数判定2
/* 直接费马小定理 */ #include<iostream> #include<cstdio> #include<cstdlib> #include<ct ...
- target,currentTarget,delegateTarget,srcElement
第一种情况:就是IE9+和其他现代浏览器,支持addEventListener方法.其结果是: this总是等于currentTarget currentTarget总是事件监听者 target总是事 ...
- Python os常用模块
Python的标准库中的os模块包含普遍的操作系统功能.如果你希望你的程序能够与平台无关的话,这个模块是尤为重要的.即它允许一个程序在编写后不需要任何改动,也不会发生任何问题,就可以在Linux和Wi ...
- Swift - 30 - 可变参数
//: Playground - noun: a place where people can play import UIKit // 可变参数一定要放在所有定义参数的最后面, 和其他参数的定义方式 ...
- backbone学习笔记(一)
因为工作的需要,从今天起对backbone的学习过程做下记录. 学习计划: 1.1周看基本知识(2014/1/18-2014/1/25) 2.基本知识总结(2014/1/26) 3.半周按教程写hel ...