题意:一棵树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. 转:ASP.NET中的SESSION实现与操作方法

    在ASP.NET中,状态的保持方法大致有:ApplicationState,SessionState,Cookie,配置文件,缓存. ApplicationState 的典型应用如存储全局数据. Se ...

  2. ArcSDE for oracle10g安装后post的时候出现错误

    The Post Installation Setup can not locate required Oracle files in your path.Check your Oracle inst ...

  3. vm安装mac系统

    零:起因想学习IOS开发,但是mac pro和mac mini都舍不得买,去apple店体验了几次mac不怎么喜欢,so… 一:原料VMware-workstation-full-12.0.0-298 ...

  4. ZigBee绑定细节

    ZigBee中的绑定由APS层来管理,除了绑定表管理外,APS层还有组表管理.快速地址查找等服务功能.应用层不能直接调用APS层中的数据服务来传输数据,只能通过AF层封装的AD_DataRequest ...

  5. 【Delphi】窗体阴影

    procedure TForm1.FormCreate(Sender: TObject); begin SetClassLong(Handle, GCL_STYLE, GetClassLong(Han ...

  6. 编译Linux系统下的jrtplib3.9和jthread1.3(arm和ubuntu)

    最近由于学习需要,需要编译jrtplib,网上的资料基本上都是关于3.9以前的版本,而以前的版本基本上都是通过confiugre来配置生成Makefile,而最近的版本却没有这一项,而是使用cmake ...

  7. Python+PyQt 数据库基本操作

    Sqlite: 使用Python的sqlite3: 需要注意下commit方式与qt稍有不同 import sqlite3 class DBManager(): def __init__(self): ...

  8. C语言-人狼羊菜问题-最容易看懂的解决方法及代码

    题目描述:农夫需要把狼.羊.菜和自己运到河对岸去,只有农夫能够划船,而且船比较小,除农夫之外每次只能运一种东西,还有一个棘手问题,就是如果没有农夫看着,羊会偷吃菜,狼会吃羊.请考虑一种方法,让农夫能够 ...

  9. 巧用system函数个性化屏幕显示

    函数名:system 功  能: 发出一个DOS命令 用  法: system("DOS命令");             (system函数需加头文件<stdlib.h&g ...

  10. EXPLAIN PLAN获取SQL语句执行计划

    一.获取SQL语句执行计划的方式 1. 使用explain plan 将执行计划加载到表plan_table,然后查询该表来获取预估的执行计划 2. 启用执行计划跟踪功能,即autotrace功能 3 ...