就贴个代码

#include <cstdio>
#include <algorithm> typedef long long LL;
const int MN = 200005, MS = 524289; int N, Q, h[MN], nxt[MN * 2], to[MN * 2], tot;
inline void ins(int x, int y) { nxt[++tot] = h[x], to[tot] = y, h[x] = tot; } int dep[MN], faz[MN], siz[MN], son[MN], top[MN], ldf[MN], rdf[MN], idf[MN], dfc;
void DFS0(int u, int fz) {
dep[u] = dep[faz[u] = fz] + 1, siz[u] = 1;
for (int i = h[u]; i; i = nxt[i]) {
if (to[i] == fz) continue;
DFS0(to[i], u);
siz[u] += siz[to[i]];
if (siz[son[u]] < siz[to[i]]) son[u] = to[i];
}
}
void DFS1(int u, int t) {
top[u] = t, idf[ldf[u] = ++dfc] = u;
if (son[u]) DFS1(son[u], t);
for (int i = h[u]; i; i = nxt[i]) {
if (to[i] == faz[u] || to[i] == son[u]) continue;
DFS1(to[i], to[i]);
}
rdf[u] = dfc;
}
inline int LCA(int u, int v) {
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) std::swap(u, v);
u = faz[top[u]];
}
return dep[u] < dep[v] ? u : v;
}
inline int Dist(int u, int v) { return dep[u] + dep[v] - 2 * dep[LCA(u, v)]; } #define li (i << 1)
#define ri (i << 1 | 1)
#define mid ((l + r) >> 1)
#define ls li, l, mid
#define rs ri, mid + 1, r
namespace T1 {
int len[MS];
LL sa[MS], sb[MS], tgk[MS], tgb[MS], tgv[MS];
bool tg[MS];
inline void P(int i, LL k, LL b, LL v) {
sa[i] += (LL)(len[i] + 1) * len[i] / 2 * k + len[i] * b + sb[i] * v;
tgk[i] += k, tgb[i] += b, tgv[i] += v;
tg[i] = 1;
}
inline void PushDown(int i) {
if (tg[i]) {
P(li, tgk[i], tgb[i], tgv[i]);
P(ri, tgk[i], tgb[i] + len[li] * tgk[i], tgv[i]);
tgk[i] = tgb[i] = tgv[i] = 0;
tg[i] = 0;
}
}
void Build(int i, int l, int r) {
len[i] = r - l + 1;
if (l == r) { sb[i] = dep[idf[l]]; return ; }
Build(ls), Build(rs);
sb[i] = sb[li] + sb[ri];
}
void Mdf1(int i, int l, int r, int a, int b, LL x, LL y) {
if (r < a || b < l) return ;
if (a <= l && r <= b) return P(i, x, y + (l - a) * x, 0);
PushDown(i);
Mdf1(ls, a, b, x, y), Mdf1(rs, a, b, x, y);
sa[i] = sa[li] + sa[ri];
}
void Mdf2(int i, int l, int r, int a, int b, LL x) {
if (r < a || b < l) return ;
if (a <= l && r <= b) return P(i, 0, 0, x);
PushDown(i);
Mdf2(ls, a, b, x), Mdf2(rs, a, b, x);
sa[i] = sa[li] + sa[ri];
}
LL Qur(int i, int l, int r, int a, int b) {
if (r < a || b < l) return 0ll;
if (a <= l && r <= b) return sa[i];
PushDown(i);
return Qur(ls, a, b) + Qur(rs, a, b);
} inline void ChainAdd(int x, int y, LL k, LL b) {
int len = Dist(x, y) + 1;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) {
b += (len + 1) * k, k = -k;
std::swap(x, y);
}
Mdf1(1, 1, N, ldf[top[x]], ldf[x], -k, b + (dep[x] - dep[top[x]] + 2) * k);
b += (dep[x] - dep[top[x]] + 1) * k;
len -= dep[x] - dep[top[x]] + 1;
x = faz[top[x]];
}
if (dep[x] > dep[y]) {
b += (len + 1) * k, k = -k;
std::swap(x, y);
}
Mdf1(1, 1, N, ldf[x], ldf[y], k, b);
} inline LL ChainQur(int x, int y) {
LL Sum = 0;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) std::swap(x, y);
Sum += Qur(1, 1, N, ldf[top[x]], ldf[x]);
x = faz[top[x]];
}
if (dep[x] > dep[y]) std::swap(x, y);
return Sum + Qur(1, 1, N, ldf[x], ldf[y]);
}
} namespace T2 {
int len[MS];
LL s1[MS], s2[MS], s3[MS], sb[MS], sc[MS], tg[MS];
inline void P(int i, LL x) {
s1[i] += len[i] * x;
s2[i] += sb[i] * x;
s3[i] += sc[i] * x;
tg[i] += x;
}
inline void PushDown(int i) {
if (tg[i]) P(li, tg[i]), P(ri, tg[i]), tg[i] = 0;
}
void Build(int i, int l, int r) {
len[i] = r - l + 1;
if (l == r) { sb[i] = siz[idf[l]], sc[i] = dep[idf[l]]; return ; }
Build(ls), Build(rs);
sb[i] = sb[li] + sb[ri];
sc[i] = sc[li] + sc[ri];
}
void Mdf(int i, int l, int r, int a, int b, LL x) {
if (r < a || b < l) return ;
if (a <= l && r <= b) return P(i, x);
PushDown(i);
Mdf(ls, a, b, x), Mdf(rs, a, b, x);
s1[i] = s1[li] + s1[ri];
s2[i] = s2[li] + s2[ri];
s3[i] = s3[li] + s3[ri];
}
LL Qur(int i, int l, int r, int a, int b, int t) {
if (r < a || b < l) return 0;
if (a <= l && r <= b) return (t == 1 ? s1 : t == 2 ? s2 : s3)[i];
PushDown(i);
return Qur(ls, a, b, t) + Qur(rs, a, b, t);
}
inline void ChainAdd(int x, LL v) {
for (; x; x = faz[top[x]])
Mdf(1, 1, N, ldf[top[x]], ldf[x], v);
}
inline LL ChainQur(int x, int t) {
LL Sum = 0;
for (; x; x = faz[top[x]])
Sum += Qur(1, 1, N, ldf[top[x]], ldf[x], t);
return Sum;
}
} int main() {
int op, x, y, z; LL v;
scanf("%d", &N);
for (int i = 1; i < N; ++i) scanf("%d%d", &x, &y), ins(x, y), ins(y, x);
DFS0(1, 0), DFS1(1, 1);
T1::Build(1, 1, N);
T2::Build(1, 1, N);
scanf("%d", &Q);
while (Q--) {
scanf("%d%d", &op, &x);
if (op == 1) {
scanf("%d%lld", &y, &v);
T1::ChainAdd(x, y, 0, v);
}
if (op == 2) {
scanf("%lld", &v);
T1::Mdf1(1, 1, N, ldf[x], rdf[x], 0, v);
}
if (op == 3) {
scanf("%d%d%lld", &y, &z, &v);
int l1 = LCA(x, y), l2 = LCA(x, z), l3 = LCA(y, z);
int pos = dep[l1] > dep[l2] ? dep[l1] > dep[l3] ? l1 : l3 : dep[l2] > dep[l3] ? l2 : l3;
int dist = Dist(z, pos);
LL b = (dist - 1) * v;
T1::ChainAdd(pos, x, v, b);
T1::ChainAdd(pos, y, v, b);
T1::Mdf1(1, 1, N, ldf[pos], ldf[pos], 0, -dist * v);
}
if (op == 4) {
scanf("%d%lld", &z, &v);
if (ldf[x] < ldf[z] && ldf[z] <= rdf[x]) {
T1::Mdf2(1, 1, N, ldf[x], rdf[x], v);
T1::Mdf1(1, 1, N, ldf[x], rdf[x], 0, (Dist(z, x) - dep[x]) * v);
T2::ChainAdd(z, -2 * v);
T2::ChainAdd(x, 2 * v);
} else {
T1::Mdf2(1, 1, N, ldf[x], rdf[x], v);
T1::Mdf1(1, 1, N, ldf[x], rdf[x], 0, (Dist(z, x) - dep[x]) * v);
}
}
if (op == 5) {
LL Ans = T1::Qur(1, 1, N, ldf[x], ldf[x]);
Ans += T2::ChainQur(x, 1);
printf("%lld\n", Ans);
}
if (op == 6) {
scanf("%d", &y);
int l = LCA(x, y), len = dep[x] + dep[y] - 2 * dep[l] + 1;
LL Ans = T1::ChainQur(x, y);
LL Ql1 = T2::ChainQur(l, 1), Qx1 = T2::ChainQur(x, 1), Qy1 = T2::ChainQur(y, 1);
LL Ql3 = T2::ChainQur(l, 3), Qx3 = T2::ChainQur(x, 3), Qy3 = T2::ChainQur(y, 3);
Ans += Ql1 * len;
Ans += (Qx1 - Ql1) * (dep[x] + 1) - (Qx3 - Ql3);
Ans += (Qy1 - Ql1) * (dep[y] + 1) - (Qy3 - Ql3);
printf("%lld\n", Ans);
}
if (op == 7) {
LL Ans = T1::Qur(1, 1, N, ldf[x], rdf[x]);
Ans += T2::ChainQur(x, 1) * siz[x];
if (ldf[x] < rdf[x]) Ans += T2::Qur(1, 1, N, ldf[x] + 1, rdf[x], 2);
printf("%lld\n", Ans);
}
}
return 0;
}

NOI.AC 722: tree的更多相关文章

  1. SDOI2015 寻宝游戏 | noi.ac#460 tree

    题目链接:戳我 可以知道,我们相当于是把有宝藏在的地方围了一个圈,求这个圈最小是多大. 显然按照dfs序来遍历是最小的. 那么我们就先来一遍dfs序列,并且预处理出来每个点到根的距离(这样我们就可用\ ...

  2. # NOI.AC省选赛 第五场T1 子集,与&最大值

    NOI.AC省选赛 第五场T1 A. Mas的童年 题目链接 http://noi.ac/problem/309 思路 0x00 \(n^2\)的暴力挺简单的. ans=max(ans,xor[j-1 ...

  3. NOI.ac #31 MST DP、哈希

    题目传送门:http://noi.ac/problem/31 一道思路好题考虑模拟$Kruskal$的加边方式,然后能够发现非最小生成树边只能在一个已经由边权更小的边连成的连通块中,而树边一定会让两个 ...

  4. NOI.AC NOIP模拟赛 第五场 游记

    NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...

  5. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

  6. NOI.AC NOIP模拟赛 第二场 补记

    NOI.AC NOIP模拟赛 第二场 补记 palindrome 题目大意: 同[CEOI2017]Palindromic Partitions string 同[TC11326]Impossible ...

  7. NOI.AC NOIP模拟赛 第一场 补记

    NOI.AC NOIP模拟赛 第一场 补记 candy 题目大意: 有两个超市,每个超市有\(n(n\le10^5)\)个糖,每个糖\(W\)元.每颗糖有一个愉悦度,其中,第一家商店中的第\(i\)颗 ...

  8. NOI.AC NOIP模拟赛 第四场 补记

    NOI.AC NOIP模拟赛 第四场 补记 子图 题目大意: 一张\(n(n\le5\times10^5)\)个点,\(m(m\le5\times10^5)\)条边的无向图.删去第\(i\)条边需要\ ...

  9. NOI.AC NOIP模拟赛 第三场 补记

    NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...

随机推荐

  1. 4. jenkins 构建任务

    这边说一下 ,服务器的分布.  因为我这边 测试环境的项目比较多,不能修改主机名 1号机器 节点机器(node) 最终项目发布到这台机器 2号机器  jenkins jenkins的部署,发布 3号机 ...

  2. 【Spring AOP】AOP实现原理(六)

    原文链接:https://my.oschina.net/guangshan/blog/1797461

  3. Python中xlrd和xlwt模块使用方法----》》数据库数据导出(之一)

    xlrd模块实现对excel文件内容读取,xlwt模块实现对excel文件的写入. (1) 打开excel文件并获取所有sheet >>> import xlrd >>& ...

  4. CF-weekly4 F. Kyoya and Colored Balls

    https://codeforces.com/gym/253910/problem/F F. Kyoya and Colored Balls time limit per test 2 seconds ...

  5. Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2) C. p-binary 水题

    C. p-binary Vasya will fancy any number as long as it is an integer power of two. Petya, on the othe ...

  6. Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 背包dp

    D. Yet Another Subarray Problem You are given an array \(a_1, a_2, \dots , a_n\) and two integers \( ...

  7. Windows安装RabbitMQ并设置数据存储目录

    一.安装Elang 下载otp_win64_xx.x.exe,当前使用otp_win64_21.3.exe版本,按步骤完成安装. 下载地址:http://www.erlang.org/download ...

  8. kafka_2.12-2.2.1 集群搭建

    一.zookeeper集群搭建 kafka集群依赖于zookeeper的集群,搭建zookeeper集群的步骤参考我之前写过的,Solr集群搭建详细教程(一)中的第二步 二.下载解压 去官网下载htt ...

  9. Go 中 ORM 的 Repository(仓储)模式

    ORM 在业务开发中一直扮演着亦正亦邪的角色.很多人赞颂 ORM,认为 ORM 与面向对象的契合度让代码简洁有道.但是不少人厌恶它,因为 ORM 隐藏了太多的细节,埋下了超多的隐患.在 Go 中,我们 ...

  10. SpringBoot启用https

    1.利用JDK自带的keytool生成证书 keytool -genkey -storetype PKCS12 -alias tomcat -keyalg RSA -keysize 2048 -key ...