题意:一棵树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. CSS 元素垂直居中的 6种方法

    利用CSS进行元素的水平居中,比较简单,行级元素设置其父元素的text-align center,块级元素设置其本身的left 和 right margins为auto即可.本文收集了六种利用css进 ...

  2. OC9_字符串的内存管理

    // // main.m // OC9_字符串的内存管理 // // Created by zhangxueming on 15/6/18. // Copyright (c) 2015年 zhangx ...

  3. 移动web屏幕适配方案

    刚进部门就被拉去趟移动端Web的浑水,视觉稿是按照640px设计的.那如何做屏幕适配呢?当然想到的第一方法就是问前辈了,问他们之前怎么做的,前辈说直接按视觉稿来,我说640太大了,他说除以2啊,按32 ...

  4. zz Release memory in Linux (Unused or Cached)

    In computer science, Memory Leakage occurs when a computer software or program consumes required mem ...

  5. 2013山东省“浪潮杯”省赛 A.Rescue The Princess

    A.Rescue The PrincessDescription Several days ago, a beast caught a beautiful princess and the princ ...

  6. Ng机器学习笔记-1-一元线性回归

    一:回归模型介绍 从理论上讲,回归模型即用已知的数据变量来预测另外一个数据变量,已知的数据属性称为输入或者已有特征,想要预测的数据称为输出或者目标变量. 下图是一个例子: 图中是某地区的面积大小与房价 ...

  7. input中id和name属性的区别。

    input中id和name属性的区别. 做网站很久了,但到现在还没有搞明白input中name和id的区别,最近学习jquery,又遇到这个问题,就在网上搜集资料.看到这篇,就整理出来,以备后用. 可 ...

  8. jQuery网页元素拖拽插件

    效果说明:配合已有CSS样式,载入插件后,网页元素可以随意在窗口内拖拽,设置了原位置半透明和拖拽半透明的效果选项,可根据需要选择.另外,当页面上有多个可拖拽元素时,可以载入另外一个用于设置z-inde ...

  9. CURL模拟登陆

    index.html <a href="http://adtuu-server.com/login/login.php?auth_username=admin&auth_pas ...

  10. Spark Streaming揭秘 Day17 资源动态分配

    Spark Streaming揭秘 Day17 资源动态分配 今天,让我们研究一下一个在Spark中非常重要的特性:资源动态分配. 为什么要动态分配?于Spark不断运行,对资源也有不小的消耗,在默认 ...