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'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
随机推荐
- 解密-神秘的 RunLoop
引言 一直以来RunLoop就是个神秘的领域,好多2.3年的开发者都不能准确的表述它的作用,说它神秘,其实RunLoop并没有大家想象中的那么神秘,那么不好理解,本文就带大家好好剖析一下”神秘的Run ...
- java 线程三种实现方式
1继承thread public class MultiThread1 extends Thread{ public void run(){ for(int i=0; i<7; i++){ Sy ...
- GDataXML的配置和使用
1.下载链接:http://code.google.com/p/gdata-objectivec-client/downloads/list下载“gdata-objective-c client li ...
- android anim 动画效果(转)
动画效果编程基础--AnimationAndroid 动画类型 Android的animation由四种类型组成 XML中 alpha 渐变透明度动画效果 ...
- springmvc常见注解模式
常用注解元素 @Controller 标注在Bean的类定义处 @RequestMapping 真正让Bean具备 Spring MVC Controller 功能的是 @RequestMapping ...
- WMI使用集锦
转载:http://singlepine.cnblogs.com/articles/299457.html 1.WMI简介 WMI是英文Windows Management Instrumentati ...
- c#使用Microsoft Excel 12.0 object Libary导出的Excel文件office2003不能打开!!~~(分享)
-----转载:http://hi.baidu.com/zhang_zhu_1/item/f3d47d1f86bf037a70d5e87e 使用C#导出数据到Excel文件时,Excel 2007组件 ...
- oracle系统包——dbms job用法(oracle定时任务)
用于安排和管理作业队列,通过使用作业,可以使ORACLE数据库定期执行特定的任务. 一.dbms_job涉及到的知识点1.创建job:variable jobno number;dbms_job.su ...
- Mavne + Spring整合CXF
http://blog.csdn.net/xiongyu777888/article/details/23787615(没毛病) http://blog.csdn.net/hbsong75/artic ...
- SqlServer CTE 递归查询 Oracle递归查询
在做数据库设计这块,很多时候表的数据模型就是典型的二叉树结构. 于是在查询数据的时候,就涉及到了数据的递归查询. 递归查询分为两种:1.从根节点查询自身以及所有的子节点:2.从子节点查询自身以及所有的 ...