题意: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年北京网络赛的更多相关文章

  1. 【DFS序+线段树区间更新区间求最值】HDU 5692 Snacks

    http://acm.hdu.edu.cn/showproblem.php?pid=5692 [思路] 每更新一个点,子树的所有结点都要更新,所以是区间更新 每查询一个点,子树的所有结点都要查询,所以 ...

  2. NBOJv2 1034 Salary Inequity(DFS序+线段树区间更新区间(最值)查询)

    Problem 1034: Salary Inequity Time Limits:  10000 MS   Memory Limits:  200000 KB 64-bit interger IO ...

  3. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  4. HDU5032 -- Always Cook Mushroom 树状数组 14年北京网络赛

    题意:1000*1000的格子, 坐标为(1, 1) ~ (1000, 1000), 常数 A, B, 点(x,  y)权值为 (x + A) * (y + B), q次询问, 每次询问(0, 0) ...

  5. 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)

    P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...

  6. DFS序+线段树(bzoj 4034)

    题目链接 题目就不多说了. 本题目,可以用dfs序+线段树做:题目给定了一棵树,树上节点告诉了权值.我们可以先将这棵树进行dfs将一棵树变成线性结构:如图 变成这样后,然后就可以用线段树. 操作1:也 ...

  7. 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)

    牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...

  8. Educational Codeforces Round 6 E dfs序+线段树

    题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...

  9. BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)

    题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...

随机推荐

  1. picasso_强大的Android图片下载缓存库

    tag: android pic skill date: 2016/07/09 title: picasso-强大的Android图片下载缓存库 [本文转载自:泡在网上的日子 参考:http://bl ...

  2. Linux学习笔记共享

    从学习到现在,已经3个月了,还有不到一个月linux课程就要结束,大概的情况如下: 预科一周,主要是学习了网络,思科的内容 linux基础课程,从无到有 linux shell 脚本 linux项目实 ...

  3. 浪漫桃心的Android表白程序

    本文转载于  huachao1001的专栏 几年前,看到过有个牛人用HTML5绘制了浪漫的爱心表白动画.地址在这:浪漫程序员 HTML5爱心表白动画.发现原来程序员也是可以很浪……漫…..的.那么在A ...

  4. canvas sprite动画 简单封装

    function SpritCtx(img, size, pos, turnTime, totalCount, ctx) { size = size || {}; pos = pos || {}; / ...

  5. Javascript 获取url参数,hash值 ,cookie

    /** * 获取请求参数 * @param key * @returns {*} */ function getRequestParameter(key){ var params = getReque ...

  6. Wpf ListBox数据绑定实例1--绑定字典集合

    1.使用ListBox绑定Dictionary字典数据 ListBox常用事件SelectionChanged private void bindListBox() { Dictionary<s ...

  7. (转)PHP函数spl_autoload_register()用法和__autoload()介绍

      转--http://www.jb51.net/article/29624.htm 又是框架冲突导致__autoload()失效,用spl_autoload_register()重构一下,问题解决 ...

  8. java中的IO一

    一.IO操作的目标 IO的流向 二.IO的分类方法 1.第一种分法:输入流.输出流 2.第二种分法:字节流.字符流 3.第三种分法:节点流.处理流 三.IO当中的核心类 核心类中的核心方法 Input ...

  9. iOS开发之四张图说明GCD(Grand Central Dispatch)附Test源码

    首先,先介绍几个概念:GCD,队列,串行,并行,同步,异步.                                                                       ...

  10. iPhone真机测试Crash信息分析

    一.获取Crash Log的方式 在iOS开发过程,当应用已经打包,iPhone设备通过ipa的包安装应用后,在使用过程发现crash,那么如何获取crash日志呢,现提供如下四种获取crash日志的 ...