就贴个代码

#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. day54_9_18视图层某内部原理(fbv和cbv)与模板层

    一.render内部原理. 在render中往往需要返回三个参数,request,模板和一些键值对. 键值对中存储的是需要对模板渲染的值. 如果手动实现可以如下: from django.templa ...

  2. C++ trais技术 模板特化的应用

    // traits 的应用 /////////////////////////////////////////// // traits template <typename T> clas ...

  3. LG5104 红包发红包 概率与期望

    问题描述 LG5104 题解 观察发现,对于 \(w\) ,期望得钱是 \(\frac{w}{2}\) . 然后答案就是 \(\frac{w}{2^k}\) . 然后快速幂求个逆元就好了. \(\ma ...

  4. DRF--验证器

    前戏 在之前我们对前端妹子传来的数据进行校验,使用的是序列化类来进行校验的,但这里面往往满足不了我们的需求,更多的时候我们希望自己定义校验规则.这里介绍三种自定义校验的方式.分别是单一字段校验,多个字 ...

  5. sql 合并结果集数据

    起因:项目上查询一些数据,需要将查询后的结果合并到一列中. 1.STUFF函数 官方api: https://docs.microsoft.com/zh-cn/sql/t-sql/functions/ ...

  6. 构建Shiny应用

    构建Shiny应用 1.什么是Shiny? Shiny是一个R的应用包,帮助用户构建可交互的web应用.它可以结合HTML和CSS代码,以及R 语言的运算能力. 2.下载R Shiny 下载R包 in ...

  7. Windows Terminal (Preview)治好了cmd,powershell的癌症

    前言 话说n年前,我想开发一款powershell麻将游戏,但是发现命令行下无法显示麻将牌这种特殊符号. 经过研究发现,这是4字节的utf16le字符串.而powershell依赖的渲染引擎,只能渲染 ...

  8. jQuery 源码解析(八) 异步队列模块 Callbacks 回调函数详解

    异步队列用于实现异步任务和回调函数的解耦,为ajax模块.队列模块.ready事件提供基础功能,包含三个部分:Query.Callbacks(flags).jQuery.Deferred(funct) ...

  9. .net core linux环境下 System.Data.SqlClient.SqlException: Connection Timeout Expired.

    最近遇到了一个很奇葩的问题,我编写了一个.net core程序读取多个数据库数据源,进行数据同步处理.该程序在windows环境下运行完全正常,但在linux环境下运行报异常,提示 System.Da ...

  10. ELK学习笔记之Elasticsearch和Kibana数据导出实战

    0x00 问题引出 以下两个导出问题来自Elastic中文社区. 问题1.kibana怎么导出查询数据?问题2:elasticsearch数据导出就像数据库数据导出一样,elasticsearch可以 ...