题意:一棵树n个结点,每条边有0.1两种权值,每次询问权值为奇数的路径数目,或者改变某一条边的权值。

分析:这个题目很巧妙低利用了异或和的特性,dfs得到每个点到根结点的权值异或和,然后奇数则为1,偶数为0,异或和为0和1的点组成的路径权值和一定为奇数,询问结果就是0个数和1个数乘积2倍。

代码:

 #include <cstdio>
#include <iostream>
#include <vector>
#include <map>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#define pb push_back
#define mp make_pair #define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define sz(x) ((int)((x).size()))
#define pb push_back
#define in freopen("data.txt", "r", stdin);
#define bug(x) printf("Line : %u >>>>>>\n", (x));
#define inf 0x0f0f0f0f
using namespace std;
typedef pair<int, int> PII;
typedef map<string, int> MPS;
typedef long long LL; const int maxn = + ;
MPS mps; struct Edge {
int u, v, c;
Edge() {}
Edge(int u, int v, int c):u(u), v(v), c(c) {}
};
vector<Edge> edges;
vector<int> g[maxn]; int n, m, q, cnt;
int le[maxn], ri[maxn]; int idx(char *s) {
if(mps.count(s) == false)
mps[s] = ++cnt;
return mps[s];
} void add(int u, int v, int c) {
edges.pb(Edge(u, v, c));
edges.pb(Edge(v, u, c));
m = edges.size();
g[u].pb(m-);
g[v].pb(m-);
}
char sa[], sb[];
int cover[maxn<<], val[maxn], dep[maxn], ans[maxn<<];
void PushUp(int rt) {
ans[rt] = ans[rt<<]+ans[rt<<|];
}
//线段树的每个结点要初始化!!!! void PushDown(int l, int r, int rt) {
int m = (l+r)>>;
if(cover[rt]) {
cover[rt<<] ^= ;
cover[rt<<|] ^= ;
ans[rt<<] = m-l+-ans[rt<<];
ans[rt<<|] = r-m-ans[rt<<|];
cover[rt] = ;
}
}
void build(int l, int r, int rt) {
if(l == r) {
cover[rt] = ;
ans[rt] = val[l];
return;
}
cover[rt] = ;
int m = (l+r)>>;
build(lson);
build(rson);
PushUp(rt);
}
void update(int l, int r, int rt, int L, int R) {
if(L <= l && R >= r) {
cover[rt] ^= ;
ans[rt] = r-l+-ans[rt];
return;
} int m = (l+r)>>;
PushDown(l, r, rt);
if(L <= m)
update(lson, L, R);
if(R > m)
update(rson, L, R);
PushUp(rt);
}
void dfs(int u, int fa, int va) {
dep[u] = dep[fa] + ;
le[u] = ++cnt;
val[cnt] = va;
for(int i = ; i < (int)g[u].size(); i++) {
Edge e = edges[g[u][i]];
int v = e.v;
int c = e.c;
if(v == fa) continue;
dfs(v, u, c^va);
}
ri[u] = cnt;
}
int main() { int T;
int kase = ;
for(int t = scanf("%d", &T); t <= T; t++) {
scanf("%d", &n);
mps.clear();
cnt = ;
edges.clear();
for(int i = ; i <= n; i++) {
g[i].clear();
scanf("%s", sa);
idx(sa);
}
for(int i = ; i < n-; i++) {
int c, u, v;
scanf("%s%s%d", sa, sb, &c);
u = idx(sa);
v = idx(sb);
add(u, v, c);
}
scanf("%d", &q);
printf("Case #%d:\n", ++kase);
cnt = ;
dfs(, , );
build(, n, );
LL res = ;
while(q--) {
scanf("%s", sa);
if(sa[] == 'Q') {
res = (LL)(n-ans[])*ans[]*;
printf("%I64d\n", res);
} else {
int x;
scanf("%d", &x);
x--;
x <<= ;
int u = edges[x].u;
int v = edges[x].v;
if(dep[u] < dep[v]) swap(u, v);
update(, n, , le[u], ri[u]);
}
}
}
return ;
}

当然也有一种更复杂的方法,同Qtree4,可以拿来练手,感觉有点无聊。

HDU 5039 Hilarity的更多相关文章

  1. hdu 5039 线段树+dfs序

    http://acm.hdu.edu.cn/showproblem.php?pid=5039 给定一棵树,边权为0/1.m个操作支持翻转一条边的权值或者询问树上有多少条路径的边权和为奇数. 用树形df ...

  2. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  3. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  4. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  5. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  6. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  7. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

  8. hdu 4481 Time travel(高斯求期望)(转)

    (转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...

  9. HDU 3791二叉搜索树解题(解题报告)

    1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...

随机推荐

  1. 忍者无敌-实例讲解Cocos2d-x瓦片地图

    实例比较简单,如图所示,地图上有一个忍者精灵,玩家点击他周围的上.下.左.右,他能够向这个方向行走.当他遇到障碍物后是无法穿越的,障碍物是除了草地以为部分,包括了:树.山.河流等. 忍者实例地图(TO ...

  2. Xml 学习二

    使用PHPDOM模型操作XML XML的树状结构: s 1.xml文档 1.1.创建DOM树 //创建DOM树$M = new DOMDocument('1.0','utf-8');   1.2.加载 ...

  3. Polyline转Polygon

    IGeometry geo = feature.ShapeCopy; IGeometryCollection pPolyline = geo as IGeometryCollection; ISegm ...

  4. pure virtual、impure virtual、non-virtual函数的接口继承和实现继承

    1.abstract class 拥有pure virtual函数的class是abstract class. 不能创建abstract class的实体. 2.pure virtual 函数 他们必 ...

  5. 关键字 virtual

    Virtual是C++ OO机制中很重要的一个关键字.只要是学过C++的人都知道在类Base中加了Virtual关键字的函数就是虚拟函数(例如函数print),于是在Base的派生类Derived中就 ...

  6. Hyper-V 虚拟机连接外部网络

    Hyper-V创建好虚拟机之后,在默认配置下是没有网络连接的,这个时候就需要进行简单的配置,即可让虚拟机连接外部网络: 在Hyper-V管理器中,右键点击后出现菜单,选择"虚拟交换机管理器& ...

  7. 10套免费的响应式布局 Bootstrap 模版

    1. Cardio Cardio是我最喜欢的一个轻量级模板.它几乎可以很少的修改的用于任何类型的业务. 2. Evento Evento 是一个事件引导广告模板的形状.它是设计精美和注意细节. 3. ...

  8. Java http post

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import ...

  9. javaScript创建无边框iframe兼容ie

    <script>var m_iframe=document.createElement("iframe");m_iframe.scrolling="no&qu ...

  10. linux下挂载移动硬盘ntfs格式

    http://jingyan.baidu.com/article/f96699bba93dce894e3c1bec.html fdisk -l安装后 使用命令mount -t ntfs-3g /dev ...