mmm含树 查询点的提示

2024-05-07 08:38
文章标签 查询 提示 mmm 含树

本文主要是介绍mmm含树 查询点的提示,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这是今年GDKOI的一题:有一棵树,开始时所有结点的值都是0。有多个操作,每个操作有两种:

1.对某个点增加w,设dis(i,j)为点i到点j的最短距离,那么某个结点增加w时,对于任意一个结点j,它的值会增加w + dis(i,j)。

2.询问某点的值。

w可以忽略,因为整棵树都要加上w,只要记下所有w的和就可以了,输出答案时再加上。这题的突破口就是只需要求一个点的值,这就取决于其他发生变化的点对该点的影响。这里先结合一个样例,说明一些变量:


如图:点2,5,7,8被修改过(忽略了w)。

dis(i,j):点i到点j的最短距离。

lca(i,j):点i和点j的最近公共祖先。

dep(i):点i到根结点的距离,dep(6)= 2,dep(5)= 3。

cnt(i):以i为根的子树中的点,被修改过的次数,cnt(3)= 1,cnt(2)= 3。

deps(i):以i为根的子树中的被修改过的点的dep和,deps(2) = dep(2)+ dep(5)+ dep(7) = 1 + 3 + 3 = 7。

首先,要求任意两点i,j的距离,用dis(i,j)来表示是不好的,因为这没有内在的关系。这个可以表示成dep(i)+ dep(j)- 2 * dep(lca(i,j))。画个图就知道了。

如样例,有一个询问,询问3的值,那么它等于:

dep(3)* cnt(3) + deps(3) - 2 * dep(3)* cnt(3)

+dep(3)* (cnt(2)- cnt(3)) + (deps(2)- deps(3)) - 2 * dep(2)*(cnt(2)- cnt(3))

+dep(3)* (cnt(1)- cnt(2)) + (deps(1)- deps(2)) - 2 * dep(1)*(cnt(1)- cnt(2))

可以发现,有很多值是可以约去的,还有dep(2)= dep(3)- 1,dep(1)= dep(3)- 2,化简得:

dep(3) * cnt(1) +  deps(1) - 2 * (cnt(3) + cnt(2))。

再可以由此推到普遍:

询问点u:dep(u) * cnt(1) +  deps(1) - 2 * (cnt(u) + cnt(u的父亲) + cnt(u的父亲的父亲) + … + cnt(根的儿子))。注意不要加到根。

如此看来,我们需要的只是求cnt的和。这个可以用树链剖分来统计。

对于这些改一些,问一些的题目,不要局限于维护答案的值,可以通过维护其他的信息,以便于求答案。

贴个代码:

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;inline int getInt()
{int res = 0;char ch;for (ch = '#'; ch < '0' || ch > '9'; ch = getchar());for (; ch >= '0' && ch <= '9'; ch = getchar())res = res * 10 + (int) ch - 48;return res;
}const int N = 100007;int n;
int from[N], to[N << 1], next[N << 1], nedge;void Insert(int a, int b)
{to[nedge] = b;next[nedge] = from[a];from[a] = nedge ++;
}void Init() 
{n = getInt();memset(from, -1, sizeof(from));nedge = 0;for (int i = 0; i + 1 < n; i ++){int a = getInt() - 1, b = getInt() - 1;Insert(a, b);Insert(b, a);}
}int Q[N];
int father[N], size[N], dep[N];
int npath, top[N], len[N], belong[N], idx[N];void Split()
{int lo = 0, hi = 0;npath = 0;Q[0] = 0;father[0] = -1;dep[0] = 0;while (lo <= hi){int u = Q[lo ++];for (int e = from[u]; e != -1; e = next[e]){int v = to[e];if (v != father[u]){Q[++ hi] = v;father[v] = u;dep[v] = dep[u] + 1;}}}for (int i = n - 1; i >= 0; i --){int u = Q[i], p = -1;size[u] = 1;for (int e = from[u]; e != -1; e = next[e]){int v = to[e];if (v != father[u]){size[u] += size[v];if (p == -1 || size[v] > size[p])p = v;}}if (p == -1){belong[u] = npath;top[npath] = u;idx[u] = 0;len[npath ++] = 1;}else {int x = belong[p];top[x] = u;idx[u] = len[x] ++;belong[u] = x;}}
}int nnode;
struct Node
{Node *lch, *rch;int lo, hi;ll sum, val;inline int mi(){return (lo + hi) >> 1;}inline int size(){return hi - lo;}
}node[N << 1], *tree[N];void Build(Node *p, int lo, int hi) 
{p -> lo = lo;p -> hi = hi;p -> sum = p -> val = 0LL;if (lo + 1 == hi)p -> lch = p -> rch = NULL;else {int mi = p -> mi();p -> lch = &node[nnode ++];p -> rch = &node[nnode ++];Build(p -> lch, lo, mi);Build(p -> rch, mi, hi);}
}inline void Down(Node *p)
{p -> lch -> val += p -> val;p -> rch -> val += p -> val;p -> lch -> sum += p -> lch -> size() * p -> val;p -> rch -> sum += p -> rch -> size() * p -> val;p -> val = 0LL;
}void Modify(Node *p, int le, int ri)
{if (le <= p -> lo && ri >= p -> hi){p -> val ++;p -> sum += p -> size();}else {if (p -> val) Down(p);int mi = p -> mi();if (le < mi) Modify(p -> lch, le, ri);if (ri > mi) Modify(p -> rch, le, ri);p -> sum = p -> lch -> sum + p -> rch -> sum;}
}ll Ask(Node *p, int le, int ri)
{if (le <= p -> lo && ri >= p -> hi)return p -> sum;else {if (p -> val) Down(p);int mi = p -> mi();ll ret = 0LL;if (le < mi) ret += Ask(p -> lch, le, ri);if (ri > mi) ret += Ask(p -> rch, le, ri);return ret;}
}void Prepare()
{nnode = 0;for (int i = 0; i < npath; i ++){tree[i] = &node[nnode ++];Build(tree[i], 0, len[i]);}
}ll Find(int a, bool isask)
{int x = belong[a];ll ret = 0LL;while (x != belong[0]){if (isask) ret += Ask(tree[x], idx[a], len[x]);else Modify(tree[x], idx[a], len[x]);a = father[top[x]];x = belong[a];}if (a != 0)if (isask) ret += Ask(tree[x], idx[a], idx[0]);else Modify(tree[x], idx[a], len[x]);return ret;
}void Solve()
{ll w = 0LL, cnt = 0LL;for (int T = getInt(); T; T --)if (getInt() == 0){int u = getInt() - 1;Find(u, false);w += getInt();w += (ll) dep[u];cnt ++;}else {int u = getInt() - 1;ll res = - 2 * Find(u, true);res += w + cnt * dep[u];printf("%I64d\n", res);}
}int main()
{freopen("mmmfunc.in", "r", stdin);freopen("mmmfunc.out", "w", stdout);for (int T = getInt(); T; T --){Init();Split();Prepare();Solve();}return 0;
}



这篇关于mmm含树 查询点的提示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/966863

相关文章

浅谈mysql的sql_mode可能会限制你的查询

《浅谈mysql的sql_mode可能会限制你的查询》本文主要介绍了浅谈mysql的sql_mode可能会限制你的查询,这个问题主要说明的是,我们写的sql查询语句违背了聚合函数groupby的规则... 目录场景:问题描述原因分析:解决方案:第一种:修改后,只有当前生效,若是mysql服务重启,就会失效;

MySQL多列IN查询的实现

《MySQL多列IN查询的实现》多列IN查询是一种强大的筛选工具,它允许通过多字段组合快速过滤数据,本文主要介绍了MySQL多列IN查询的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析与优化1.

mss32.dll文件丢失怎么办? 电脑提示mss32.dll丢失的多种修复方法

《mss32.dll文件丢失怎么办?电脑提示mss32.dll丢失的多种修复方法》最近,很多电脑用户可能遇到了mss32.dll文件丢失的问题,导致一些应用程序无法正常启动,那么,如何修复这个问题呢... 在电脑常年累月的使用过程中,偶尔会遇到一些问题令人头疼。像是某个程序尝试运行时,系统突然弹出一个错误提

电脑提示找不到openal32.dll文件怎么办? openal32.dll丢失完美修复方法

《电脑提示找不到openal32.dll文件怎么办?openal32.dll丢失完美修复方法》openal32.dll是一种重要的系统文件,当它丢失时,会给我们的电脑带来很大的困扰,很多人都曾经遇到... 在使用电脑过程中,我们常常会遇到一些.dll文件丢失的问题,而openal32.dll的丢失是其中比较

电脑提示msvcp90.dll缺少怎么办? MSVCP90.dll文件丢失的修复方法

《电脑提示msvcp90.dll缺少怎么办?MSVCP90.dll文件丢失的修复方法》今天我想和大家分享的主题是关于在使用软件时遇到的一个问题——msvcp90.dll丢失,相信很多老师在使用电脑时... 在计算机使用过程中,可能会遇到 MSVCP90.dll 丢失的问题。MSVCP90.dll 是 Mic

电脑开机提示krpt.dll丢失怎么解决? krpt.dll文件缺失的多种解决办法

《电脑开机提示krpt.dll丢失怎么解决?krpt.dll文件缺失的多种解决办法》krpt.dll是Windows操作系统中的一个动态链接库文件,它对于系统的正常运行起着重要的作用,本文将详细介绍... 在使用 Windows 操作系统的过程中,用户有时会遇到各种错误提示,其中“找不到 krpt.dll”

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

MySQL中实现多表查询的操作方法(配sql+实操图+案例巩固 通俗易懂版)

《MySQL中实现多表查询的操作方法(配sql+实操图+案例巩固通俗易懂版)》本文主要讲解了MySQL中的多表查询,包括子查询、笛卡尔积、自连接、多表查询的实现方法以及多列子查询等,通过实际例子和操... 目录复合查询1. 回顾查询基本操作group by 分组having1. 显示部门号为10的部门名,员

mysql关联查询速度慢的问题及解决

《mysql关联查询速度慢的问题及解决》:本文主要介绍mysql关联查询速度慢的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql关联查询速度慢1. 记录原因1.1 在一次线上的服务中1.2 最终发现2. 解决方案3. 具体操作总结mysql

CSS模拟 html 的 title 属性(鼠标悬浮显示提示文字效果)

《CSS模拟html的title属性(鼠标悬浮显示提示文字效果)》:本文主要介绍了如何使用CSS模拟HTML的title属性,通过鼠标悬浮显示提示文字效果,通过设置`.tipBox`和`.tipBox.tipContent`的样式,实现了提示内容的隐藏和显示,详细内容请阅读本文,希望能对你有所帮助... 效