HDU 5039 Hilarity
题意:一棵树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的更多相关文章
- hdu 5039 线段树+dfs序
http://acm.hdu.edu.cn/showproblem.php?pid=5039 给定一棵树,边权为0/1.m个操作支持翻转一条边的权值或者询问树上有多少条路径的边权和为奇数. 用树形df ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- HDU 1796How many integers can you find(容斥原理)
How many integers can you find Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d ...
- hdu 4481 Time travel(高斯求期望)(转)
(转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...
- HDU 3791二叉搜索树解题(解题报告)
1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...
随机推荐
- CSS笔记---文字两边对齐
<style> .box{ width: 1000px; height: 500px; background-color: #aa0000; margin:0 auto; } .teste ...
- 学习红帽企业版RHEL 6.4的两问
(1)看了一晚上的RHEL 6.4,到现在也没分清楚服务器版和桌面版.都说两个版本是一个文件,那装上之后怎么判断这到底用的是服务器版还是桌面版?还有人说在安装过程中会要求选择,用虚拟机安装根本没看到有 ...
- 关键字 extern
定义:extern可置于变量或者函数前,以表示变量或者函数的定义在别的文件中.编译器会到其他模块中寻找其定义. extern int f(); extern int i; extern关键字 作为 ...
- iOS开发基础之排序
Objective-C 有排序的API,省了我们很多事. 主要有以下3种方法. NSComparator NSArray *unsortedArray = @[@5,@3,@8,@1,@7]; NSA ...
- xamarin.ios 豆瓣电台视频教程
视频中提到的网址: http://www.sufeinet.com/thread-655-1-1.html https://github.com/akfish/fm-terminal/blob/dev ...
- linux下rm误删除数据库文件的恢复方法
在linux redhat 5.4版本,rm误删除数据库文件的恢复过程分享.测试没有问题,可用. 1.首先测试rm 误删除数据库文件 [oracle@primary dbwdn]$ ll total ...
- PHP实现获得一段时间内所在的所有周的时间
function getWeek($startdate,$enddate) { //参数不能为空 if(!empty($startdate) && !empty($enddate)){ ...
- 思道OA PK 通达OA 同场竞技 谁与争锋
技术架构 思道OA 通达OA 开发语言 微软ASP.NET 4.0 PHP开源脚本语言 64位平台 64位 32位 数据库 SQL Server大数据库 MySQL开源数据库 官网下载 下载地址 下载 ...
- aliexpress 上传图
首先,图片转化为字节流 public byte[] ImagefileToByte(string srcImagePath) { System.IO.MemoryStream m = new Syst ...
- Oracle SGA参数调整
一. SGA的组成: 自动 SGA 管理后,Oracle 可以自动为我们调整以下内存池的大小: shared pool buffer cache large pool java pool stream ...