HDU 5039 Hilarity
来源:互联网 发布:航天税控发票软件 编辑:程序博客网 时间:2024/06/13 23:42
题意:
一棵树上有些边是1有些是0 问 有几条简单路径路过奇数个1 树上的边的1和0可以修改
思路:
不会做… 看题解才找到思路… TAT
首先要明确一点 对于u->v这条路径 它的奇偶是可以通过root->u和root->v计算的 因为如果从root出发的两路径不相交 那么两路径上的1相加即可判断u->v 如果相交 假设相交部分有x个1 那么对于u->v的1的个数即为两路径相加 再减去2x 很明显减2x不影响奇偶性 因此本题可以得出结论 如果从root出发有y个奇数路径 则答案为 y*((n-1)-y+1) = y*(n-y) 式子中用(n-1)是因为不算root 后面+1是因为奇数路径可以直接当答案不与偶数路径拼接
知道了如何求答案 再来想如何维护边修改 我们发现 修改一条边fu->fv 只影响fv子树中的奇偶性 那么可以用dfs序表示出树的线性结构 再通过线段树区间更新来达到目的
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<cassert>#include<vector>#include<set>#include<map>#include<queue>using namespace std;typedef long long LL;#define N 30010#define L(x) (x<<1)#define R(x) ((x<<1)|1)#define MI(x,y) ((x+y)>>1)int T, t, n, m, tot, idx;int head[N], l[N], r[N], val[N];struct edge {int u, v, flag, next;} ed[N * 2];map<string, int> hash;struct tree {int l, r, odd, lazy;} d[N * 4];void add(int u, int v, int f) {ed[tot].u = u;ed[tot].v = v;ed[tot].flag = f;ed[tot].next = head[u];head[u] = tot++;}void dfs(int u, int f, int fa) {idx++;val[idx] = f;l[u] = idx;for (int i = head[u]; ~i; i = ed[i].next) {if (ed[i].v != fa)dfs(ed[i].v, f ^ ed[i].flag, u);}r[u] = idx;}void down(int i) {if (d[i].lazy) {d[L(i)].lazy ^= 1;d[R(i)].lazy ^= 1;d[L(i)].odd = d[L(i)].r - d[L(i)].l + 1 - d[L(i)].odd;d[R(i)].odd = d[R(i)].r - d[R(i)].l + 1 - d[R(i)].odd;d[i].lazy = 0;}}void up(int i) {d[i].odd = d[L(i)].odd + d[R(i)].odd;}void init(int l, int r, int i) {d[i].l = l;d[i].r = r;d[i].lazy = 0;d[i].odd = val[l];if (l == r)return;int mid = MI(l,r);init(l, mid, L(i));init(mid + 1, r, R(i));up(i);}void update(int l, int r, int i) {if (d[i].l == l && d[i].r == r) {d[i].odd = d[i].r - d[i].l + 1 - d[i].odd;d[i].lazy ^= 1;return;}down(i);int mid = MI(d[i].l,d[i].r);if (r <= mid)update(l, r, L(i));else if (l > mid)update(l, r, R(i));else {update(l, mid, L(i));update(mid + 1, r, R(i));}up(i);}int main() {int i, u, v, f;char str[50], uu[50], vv[50];scanf("%d", &T);for (t = 1; t <= T; t++) {printf("Case #%d:\n", t);hash.clear();scanf("%d", &n);for (i = 1; i <= n; i++) {scanf("%s", str);hash[string(str)] = i;head[i] = -1;}tot = 0;for (i = 1; i < n; i++) {scanf("%s%s%d", uu, vv, &f);u = hash[string(uu)];v = hash[string(vv)];add(u, v, f);add(v, u, f);}idx = 0;dfs(1, 0, 0);init(1, n, 1);scanf("%d", &m);while (m--) {scanf("%s", str);if (str[0] == 'Q')printf("%d\n", d[1].odd * (n - d[1].odd) * 2);else {scanf("%d", &f);f = (f - 1) * 2;u = ed[f].u;v = ed[f].v;if (l[u] > l[v])update(l[u], r[u], 1);elseupdate(l[v], r[v], 1);}}}return 0;}
0 0
- HDU 5039 Hilarity
- 【HDU】5039 Hilarity 线段树
- hdu 5039 Hilarity(dfs序 + 线段树)
- [HDU 5039 Hilarity] DFS序+线段树
- HDU 5039 Hilarity dfs序、线段树
- HDU 5039 Hilarity(dfs序+线段树)
- 【线段树】 HDOJ 5039 Hilarity
- HDU Hilarity (dfs序+线段树)
- dfs+线段树(hdu5039 - Hilarity)
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- 四天精通shell编程(四)
- Oracle VM VirtualBox安装centos 7
- head及body
- 理解 this.initialize.apply ( this, arguments )
- 关于 PostgreSQL 监控工具的学习
- HDU 5039 Hilarity
- SGU 108. Self-numbers 2 离线+位优化
- Android蓝牙编程经验总结——同时传输数据和音频
- 机房管理--如何应对学生关闭极域电子教室
- Android中RelativeLayout各个属性的含义
- 处理oracle逻辑备库不应用某一个特定dml语句
- java中使用mysql查询 条件中含有中文时查询不到结果解决方案
- jQuery的Ajax跨域请求
- 高校信息化建设发展方向——资源利用