bzoj3862: Little Devil I
来源:互联网 发布:刘若英演唱会 知乎 编辑:程序博客网 时间:2024/05/17 07:13
题面在这里
题目大意:
给一棵树,每条边有黑白两种颜色。有3种操作:
- 一条链上的边的颜色取反(黑->白,白->黑);
- 与一条链相邻的边的颜色取反,相邻就是指只有一个点在链上的边;
- 询问某条链上黑边的数量。
开始时边的颜色都是白。
做法:
1操作和3操作就是普通的树剖+线段树,很容易维护。
主要是2操作。
我们考虑维护两棵线段树,
具体的细节见代码。
/************************************************************* Problem: bzoj 3862 Little Devil I User: fengyuan Language: C++ Result: Accepted Time: 3056 ms Memory: 12420 kb Submit_Time: 2017-12-07 10:53:32*************************************************************/#include<bits/stdc++.h>#define rep(i, x, y) for (int i = (x); i <= (y); i ++)#define down(i, x, y) for (int i = (x); i >= (y); i --)#define mid ((l+r)/2)#define lc (o<<1)#define rc (o<<1|1)#define pb push_back#define mp make_pair#define PII pair<int, int>#define F first#define S second#define B begin()#define E end()using namespace std;typedef long long LL;//headconst int N = 100010;int n, m, cnt, clk;int head[N], depth[N], fa[N], sz[N], son[N], top[N], p[N], sum[2][N<<2], tag[2][N<<2];struct Edge{ int to, nex;}e[N<<1];inline void add(int x, int y){ e[++ cnt].to = y; e[cnt].nex = head[x]; head[x] = cnt;}inline void dfs(int u, int last, int s){ depth[u] = s; fa[u] = last; sz[u] = 1; for (int i = head[u]; i; i = e[i].nex){ int v = e[i].to; if (v == last) continue; dfs(v, u, s+1); sz[u] += sz[v]; if (!son[u] || sz[v] > sz[son[u]]) son[u] = v; }}inline void dfs2(int u, int t){ top[u] = t; p[u] = ++ clk; if (son[u]) dfs2(son[u], t); for (int i = head[u]; i; i = e[i].nex){ int v = e[i].to; if (v == fa[u] || v == son[u]) continue; dfs2(v, v); }}inline void pushup(int t, int o){ sum[t][o] = sum[t][lc] + sum[t][rc]; }inline void pushdown(int t, int o, int l, int r){ if (!tag[t][o]) return; sum[t][lc] = mid-l+1-sum[t][lc]; sum[t][rc] = r-mid-sum[t][rc]; tag[t][lc] ^= 1; tag[t][rc] ^= 1; tag[t][o] = 0;}inline void update(int t, int o, int l, int r, int x, int y){ if (l == x && r == y){ sum[t][o] = r-l+1-sum[t][o]; tag[t][o] ^= 1; return; } pushdown(t, o, l, r); if (y <= mid) update(t, lc, l, mid, x, y); else if (x > mid) update(t, rc, mid+1, r, x, y); else update(t, lc, l, mid, x, mid), update(t, rc, mid+1, r, mid+1, y); pushup(t, o);}inline void change(int x, int y, int flag){ while (top[x] != top[y]){ if (depth[top[x]] < depth[top[y]]) swap(x, y); if (flag){ update(1, 1, 1, n, p[top[x]], p[x]); update(0, 1, 1, n, p[top[x]], p[top[x]]); if (son[x]) update(0, 1, 1, n, p[son[x]], p[son[x]]); } else update(0, 1, 1, n, p[top[x]], p[x]); x = fa[top[x]]; } if (depth[x] > depth[y]) swap(x, y); if (flag){ update(1, 1, 1, n, p[x], p[y]); update(0, 1, 1, n, p[x], p[x]); if (son[y]) update(0, 1, 1, n, p[son[y]], p[son[y]]); } else if (x != y) update(0, 1, 1, n, p[son[x]], p[y]);}inline int query(int t, int o, int l, int r, int x, int y){ if (l == x && r == y) return sum[t][o]; pushdown(t, o, l, r); if (y <= mid) return query(t, lc, l, mid, x, y); else if (x > mid) return query(t, rc, mid+1, r, x, y); else return query(t, lc, l, mid, x, mid) + query(t, rc, mid+1, r, mid+1, y);}inline int solve(int x, int y){ int ret = 0; while (top[x] != top[y]){ if (depth[top[x]] < depth[top[y]]) swap(x, y); if (top[x] != x) ret += query(0, 1, 1, n, p[son[top[x]]], p[x]); ret += query(0, 1, 1, n, p[top[x]], p[top[x]]) ^ query(1, 1, 1, n, p[fa[top[x]]], p[fa[top[x]]]); x = fa[top[x]]; } if (depth[x] > depth[y]) swap(x, y); if (x != y) ret += query(0, 1, 1, n, p[son[x]], p[y]); return ret;}int main(){ int Test; scanf("%d", &Test); while (Test --){ cnt = 0; memset(head, 0, sizeof head); memset(son, 0, sizeof son); scanf("%d", &n); rep(i, 1, n-1){ int x, y; scanf("%d%d", &x, &y); add(x, y); add(y, x); } clk = 0; dfs(1, 0, 0); dfs2(1, 1); memset(sum, 0, sizeof sum); memset(tag, 0, sizeof tag); scanf("%d", &m); while (m --){ int opt, x, y; scanf("%d%d%d", &opt, &x, &y); opt --; if (opt == 2) printf("%d\n", solve(x, y)); else change(x, y, opt); } } return 0;}
阅读全文
0 0
- bzoj3862: Little Devil I
- 【BZOJ3862】Little Devil I【树链剖分】【线段树】
- 【hdu 4897】Little Devil I
- hdu 4897 Little Devil I
- hdu 4897 Little Devil I 树链剖分
- 【HDU】4987 Little Devil I 树链剖分
- hdu4897 Little Devil I(树链剖分+线段树)
- 【HDU 4897 多校联合】Little Devil I【树链刨分】
- hdu 4897 Little Devil I(树链剖分+线段树)
- hdu 4897 Little Devil I 树剖(题如其名..)
- bzoj 3862: Little Devil I (树链剖分+线段树)
- hdu_4897_Little Devil I(树链剖分)
- HDU4905--The Little Devil II(四边形不等式优化)
- bzoj3862Little Devil I(树链剖分+线段树)
- 【HDU 4905 多校联合】The Little Devil II【DP+四边形不等式优化】
- hdu 4905 The Little Devil II 区间DP 四边形不等式优化
- hdu 4905 The Little Devil II 多校第四场 DP
- I'm a little excited today!
- 第14周项目1(1)- 验证算法直接插入排序
- 自动正则表达式生成网站
- 大数据时代的隐私保护(二)
- CentOS安装 Nginx
- Servlet简介
- bzoj3862: Little Devil I
- java.lang.NumberFormatException: For input string: "undefined"
- Linux115条常用命令
- 为什么需要搭建B2B2C商城
- java中interface的详解
- 第10章、名称解析
- 小马哥IOS 基础第一天
- Java连接Redis
- windows一键安装PHP环境wampserver,配置运行PHPRAP项目