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'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
随机推荐
- python小练习,打出1-100之间的所有偶数,设计一个函数,在桌面上创建10个文件,并以数字命名,复利计算函数
练习一:打出1-100之间的所有偶数 def even_print(): for i in range(1,101): if i % 2 == 0: print (i) even_print() #列 ...
- AS 进行单元测试
以下为本人在AndroidStudio 2.0 上实测后得出的结论,不像网上那一堆堆的误人子弟的文章,都是过时的或者根本就是不对的. 简介 和eclipse需要配置清单文件不同,AndroidStud ...
- poj 1125 Stockbroker Grapevine (dij优化 0ms)
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #defin ...
- OpenXmlSdk导出Excel
感觉OpenXmlSdk的语法真的不是很友好.研究了半天,只实现了简单的导出功能.对于单元格样式的设置暂时还是搞明白,网上的资料真的很少,官方文档是英文的.中文的文章大都是用工具(Open XML S ...
- 关于开发C#中的asp.net中gridview控件的使用
原文网址:http://blog.sina.com.cn/s/blog_67f1b4b201017663.html 1.GridView无代码分页排序: 效果图: 1.AllowSorting设为Tr ...
- class-loader.
the jdk hierarchical relationship of class-loader ----Module Class Loading and Bootstrapping---- boo ...
- Lucene.net 从创建索引到搜索的代码范例
关于Lucene.Net的介绍网上已经很多了在这里就不多介绍Lucene.Net主要分为建立索引,维护索引和搜索索引Field.Store的作用是通过全文检查就能返回对应的内容,而不必再通过id去DB ...
- SQL In的替换
前2天在搞SQL的的时候,发现其中有很多in的操作,诸如:id in(1,2,3)或id in(select id from table……),这个对SQL来说并不是最好的选择,执行效率是偏低的[它执 ...
- C#字符串string的常用使用方法
1--->字符串的声明: 1.string s=new string(char[] arr) //根据一个字符数组声明字符串,即将字符字组转化为字符串. 2.string s=new s ...
- 对于方法 String.Contains,只支持可在客户端上求值的参数。
var ProjectLevel_XJJS = "06,07,08,09"; p.Where(e =>ProjectLevel_XJJS.Contains(e.LevelCo ...