Codeforces 916E Jamie and Tree (换根讨论)
题目链接 Jamie and Tree
题意 给定一棵树,现在有下列操作:
$1$、把当前的根换成$v$;$2$、找到最小的同时包含$u$和$v$的子树,然后把这棵子树里面的所有点的值加$x$;
$3$、查询以$v$为根的子树的点权之和。
这道题其他都是常规操作,就是当前根结点为$cnt$的时候求$x$和$y$的$LCA$(操作$2$要用到)
我们假定解题的时候根一直不变(我一般都设$1$为根结点)
答案为$LCA(x,y)$ $xor$ $LCA(x, cnt)$ $xor$ $LCA(y, cnt)$
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define lson i << 1, L, mid
#define rson i << 1 | 1, mid + 1, R typedef long long LL; const int N = 1e5 + 10;
const int ass = 4e5; vector <int> v[N]; int ti;
int tot;
int n, m;
int fp[N];
int deep[N], f[N], st[N], ed[N], father[N], sz[N], son[N];
int top[N];
int cnt; LL a[N];
LL sum[N << 2], lazy[N << 2]; void dfs1(int x, int fa, int dep){
deep[x] = dep;
father[x] = fa;
son[x] = 0;
sz[x] = 1;
st[x] = ++ti; for (auto u : v[x]){
if (u == fa) continue;
dfs1(u, x, dep + 1);
sz[x] += sz[u];
if (sz[son[x]] < sz[u]) son[x] = u;
}
ed[x] = ti;
} void dfs2(int x, int tp){
top[x] = tp;
f[x] = ++tot;
fp[f[x]] = x;
if (son[x]) dfs2(son[x], tp);
for (auto u : v[x]){
if (u == father[x] || u == son[x]) continue;
dfs2(u, u);
}
} int LCA(int x, int y){
for (; top[x] ^ top[y]; ){
if (deep[top[x]] < deep[top[y]]) swap(x, y);
x = father[top[x]];
} return deep[x] > deep[y] ? y : x;
} int twz(int x, int y){
int t;
for (; top[x] ^ top[y]; ) t = top[y], y = father[top[y]];
return x == y ? t : son[x];
} inline void pushup(int i){
sum[i] = sum[i << 1] + sum[i << 1 | 1];
} inline void pushdown(int i, int L, int R){
if (L == R) return;
int mid = (L + R) >> 1;
lazy[i << 1] += 1ll * lazy[i];
sum[i << 1] += 1ll * lazy[i] * (mid - L + 1);
lazy[i << 1 | 1] += 1ll * lazy[i];
sum[i << 1 | 1] += 1ll * lazy[i] * (R - mid);
lazy[i] = 0;
} void build(int i, int L, int R){
if (L == R){ sum[i] = 1ll * a[fp[L]]; return; }
int mid = (L + R) >> 1;
build(lson);
build(rson);
pushup(i);
} void update(int i, int L, int R, int l, int r, LL val){
if (l == L && R == r){
sum[i] += 1ll * val * (R - L + 1);
lazy[i] += 1ll * val;
return ;
} pushdown(i, L, R);
int mid = (L + R) >> 1;
if (r <= mid) update(lson, l, r, val);
else if (l > mid) update(rson, l, r, val);
else{
update(lson, l, mid, val);
update(rson, mid + 1, r, val);
} pushup(i);
} LL query(int i, int L, int R, int l, int r){
pushdown(i, L, R);
if (L == l && R == r) return sum[i];
int mid = (L + R) >> 1;
if (r <= mid) return query(lson, l, r);
else if (l > mid) return query(rson, l, r);
else return query(lson, l, mid) + query(rson, mid + 1, r);
} LL calc(int x){
return query(1, 1, n, f[x], f[x] + sz[x] - 1);
} LL work(int x, LL val){
update(1, 1, n, f[x], f[x] + sz[x] - 1, val);
} int calc_lca(int x, int y, int cnt){
return LCA(x, y) ^ LCA(x, cnt) ^ LCA(y, cnt);
} int main(){ scanf("%d%d", &n, &m);
rep(i, 1, n) scanf("%lld", a + i); ti = 0;
rep(i, 2, n){
int x, y;
scanf("%d%d", &x, &y);
v[x].push_back(y);
v[y].push_back(x);
} dfs1(1, 0, 0);
dfs2(1, 1); build(1, 1, n); cnt = 1; int ca = 0;
while (m--){
int op;
scanf("%d", &op); if (op == 3){
int x;
scanf("%d", &x);
if (x == cnt){
printf("%lld\n", calc(1));
continue;
} int lca = LCA(x, cnt);
if (lca == x){
int y = twz(x, cnt);
printf("%lld\n", calc(1) - calc(y));
continue;
} printf("%lld\n", calc(x));
} else if (op == 1){
int x;
scanf("%d", &x);
cnt = x;
} else{
int x, y;
LL val;
scanf("%d%d%lld", &x, &y, &val); int z = calc_lca(x, y, cnt);
if (z == cnt){
work(1, val);
continue;
} int lca = LCA(z, cnt);
if (lca == z){
int yy = twz(z, cnt);
work(1, val);
work(yy, -val);
continue;
} work(z, val);
}
} return 0;
}
Codeforces 916E Jamie and Tree (换根讨论)的更多相关文章
- CodeForces 916E Jamie and Tree(树链剖分+LCA)
To your surprise, Jamie is the final boss! Ehehehe. Jamie has given you a tree with n vertices, numb ...
- codeforces 916E Jamie and Tree dfs序列化+线段树+LCA
E. Jamie and Tree time limit per test 2.5 seconds memory limit per test 256 megabytes input standard ...
- BZOJ 3083 遥远的国度 (换根讨论 + 树链剖分)
题目链接 BZOJ3083 换根不能真正地换. 令当前的根为$cnt$,要查找的子树根为$x$ $1$.$x = cnt$,那么要查找的区域就是整棵树. $2$.$x$在以$cnt$为根的子树内,那 ...
- Jamie and Tree CodeForces - 916E (换根)
大意: n节点树, 每个点有权值, 三种操作: 1,换根. 2, lca(u,v)的子树权值全部增加x. 3, 查询子树权值和. 先不考虑换根, 考虑子树x加v的贡献 (1)对fa[x]到根的树链贡献 ...
- Codeforces Round #527 (Div. 3) F. Tree with Maximum Cost 【DFS换根 || 树形dp】
传送门:http://codeforces.com/contest/1092/problem/F F. Tree with Maximum Cost time limit per test 2 sec ...
- Codeforces 1092 F Tree with Maximum Cost (换根 + dfs)
题意: 给你一棵无根树,每个节点有个权值$a_i$,指定一个点u,定义$\displaystyle value = \sum^v a_i*dist(u,v)$,求value的最大值 n,ai<= ...
- Codeforces 891D - Sloth(换根 dp)
Codeforces 题面传送门 & 洛谷题面传送门 换根 dp 好题. 为啥没人做/yiw 首先 \(n\) 为奇数时答案显然为 \(0\),证明显然.接下来我们着重探讨 \(n\) 是偶数 ...
- E. Tree Painting(树形换根dp)
http://codeforces.com/contest/1187/problem/E 分析:问得分最高,实际上就是问以哪个节点出发得到的分数最多,而呈现成代码形式就变成了换根,max其得分!!!而 ...
- Codeforces 997D - Cycles in product(换根 dp)
Codeforces 题面传送门 & 洛谷题面传送门 一种换根 dp 的做法. 首先碰到这类题目,我们很明显不能真的把图 \(G\) 建出来,因此我们需要观察一下图 \(G\) 有哪些性质.很 ...
随机推荐
- 笔记-编程-IO模型
笔记-编程-IO模型 1. 简介 常用IO模型 1) 同步阻塞IO(Blocking IO) 2) 同步非阻塞IO(Non-blocking IO) 3) IO ...
- poj 3308 Paratroopers(二分图最小点权覆盖)
Paratroopers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8954 Accepted: 2702 Desc ...
- 4152: [AMPPZ2014]The Captain
4152: [AMPPZ2014]The Captain Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1561 Solved: 620[Submi ...
- Jetty,Tomcat对MIME协议的配置参数说明
此处做一下小的汇总,针对Jetty容器内,存在excel的xlsx文件直接通过链接的方式下载的时候,如果是在Chrome浏览器时,则直接触发浏览器的下载行为,但是在IE11的浏览器上,则浏览器会直 ...
- C#编程:正则表达式验证身份证校验码-10
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- 云计算之路-阿里云上:用上了开放缓存服务OCS
你知道在我们使用的云服务器中哪台最贵吗?跑memcached的缓存服务器(12G内存).你知道保证网站访问速度的功臣之一是谁吗?跑memcached的缓存服务器. 用云服务器这么高贵的内存跑memca ...
- aircrack-ng破解wlan无线流量包
记录一下新的知识点. 无线协议里最关键的就是EAPOL协议了,这个里面保存着密钥,所以破解无线流量包也应该从这里入手. 用到的工具是aircrack-ng,这个在kali自带,也可以下载windows ...
- python(或BAT脚本)自动执行adb shell以后的命令
最近在用python做一个小工具,自动执行一些adb shell命令,使用subprocess.Popen来实现. 不过遇到个问题就是执行adb shell后就无法执行后面adb shell里的命 ...
- rm 、git rm 、git rm --cached的区别
rm 删除文件 git rm git rm 当我们需要删除暂存区或分支上的文件, 同时工作区也不需要这个文件了, 可以使用git rm git rm file = rm file+ git add f ...
- hdu 3721 树的直径
思路:枚举+树的直径 #include<iostream> #include<cstring> #include<cstdio> #include<algor ...