[ZJOI2015] 幻想乡战略游戏(树链剖分 + 线段树二分 + 带权重心)

problem

luogu-P3345

solution

这是一个带权重心的题,考察动态点分治。点分治?呵,不可能的,这辈子都不可能写点分治

我们重新考虑重心的性质:以这个点为根时,所有子树的大小不会超过整体大小的一半。

带权重心无非是树上每个点不再是等权的 111,而是 did_idi

考虑随机从一个点走向重心:当前假设重心为 xxx,我们维护一个值 sizxsiz_xsizx 表示 xxx 所在子树所有节点的权值和。

那么如果存在一个 xxx 的子节点 yyy,满足 2∗sizy>2*siz_y>2sizy> xxx 树中所有点的权值和,则 yyy 更优,否则 xxx 更优。

比较暴力的想法就是从根节点一路往下找,但这样每次 O(n)O(n)O(n) 搜一遍树时间开销过大,这是因为走了很多没有用的点。

因此我们考虑树链剖分,这样可以获得一个 dfs\text{dfs}dfs 序,然后用线段树维护区间 sizsizsiz 的最大值。

树链剖分得到的 dfs\text{dfs}dfs 序中深度深的节点 dfs\text{dfs}dfs 序更大。

查询时就在线段树上二分,每次分为 [l,mid],(mid,r][l,mid],(mid,r][l,mid],(mid,r],只要 (mid,r](mid,r](mid,r] 区间的最大值满足重心判断就往右子树走,否则走左子树。

时间复杂度 O(log⁡n)O(\log n)O(logn)


现在假设已经求出了重心 xxx,接下来考虑如何计算答案。
ans=∑idi∗dis(x,i)=∑idi∗(depx+depi−2∗deplca(x,i))=depx∑di+∑di∗depi−2∑di∗deplca(x,i)ans=\sum_id_i*dis(x,i)=\sum_id_i*(dep_x+dep_i-2*dep_{lca(x,i)}) \\=dep_x\sum d_i+\sum d_i*dep_i-2\sum d_i*dep_{lca(x,i)} ans=ididis(x,i)=idi(depx+depi2deplca(x,i))=depxdi+didepi2dideplca(x,i)
∑di,∑di∗depi\sum d_i,\sum d_i*dep_idi,didepi 直接用两个变量维护即可,问题在于如何维护 ∑di∗deplca(x,i)\sum d_i*dep_{lca(x,i)}dideplca(x,i)

其实这是一个很经典的树链剖分维护形式。

di←+wd_i\leftarrow +wdi+w 时,把 iii 到根路径上所有点均 +w+w+w,然后查询 xxx 到根路径上的点权值和。

先树差分一下,即在线段树中 iii 存储 depi−depfaidep_i-dep_{fa_i}depidepfai。这样从 iii 一路加到根上面算出的才是 iii 这个点本身的实际贡献。

很好写,时间复杂度 O(nlog⁡2n)O(n\log ^2n)O(nlog2n) 也能跑过。

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define maxn 100005
int n, Q;
vector < pair < int, int > > G[maxn];
int f[maxn], dep[maxn], dfn[maxn], id[maxn];namespace SGT {struct node { int Max, sum, val, tag; }t[maxn << 2];#define lson now << 1#define rson now << 1 | 1#define mid  (l + r >> 1)void build( int now, int l, int r ) {if( l == r ) { t[now].val = dep[id[l]] - dep[f[id[l]]]; return; }build( lson, l, mid );build( rson, mid + 1, r );t[now].val = t[lson].val + t[rson].val;}void pushdown( int now ) {if( ! t[now].tag ) return;t[lson].tag += t[now].tag;t[lson].Max += t[now].tag;t[lson].sum += t[lson].val * t[now].tag;t[rson].tag += t[now].tag;t[rson].Max += t[now].tag;t[rson].sum += t[rson].val * t[now].tag;t[now].tag = 0;}void modify( int now, int l, int r, int L, int R, int x ) {if( R < l or r < L ) return;if( L <= l and r <= R ) { t[now].tag += x;t[now].Max += x;t[now].sum += t[now].val * x;return;}pushdown( now );modify( lson, l, mid, L, R, x );modify( rson, mid + 1, r, L, R, x );t[now].Max = max( t[lson].Max, t[rson].Max );t[now].sum = t[lson].sum + t[rson].sum;}int query( int now, int l, int r, int L, int R ) {if( R < l or r < L ) return 0;if( L <= l and r <= R ) return t[now].sum;pushdown( now );return query( lson, l, mid, L, R ) + query( rson, mid + 1, r, L, R );}int query( int x ) {int now = 1, l = 1, r = n;while( l ^ r ) {pushdown( now );if( t[rson].Max >= x ) now = rson, l = mid + 1;else now = lson, r = mid;}return id[l];}
}namespace Qtree {int cnt = 0;int son[maxn], siz[maxn], top[maxn];void dfs1( int u, int fa ) {f[u] = fa; siz[u] = 1;for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i].first, w = G[u][i].second;if( v == fa ) continue;else dep[v] = dep[u] + w, dfs1( v, u );siz[u] += siz[v];if( siz[v] > siz[son[u]] ) son[u] = v;}}void dfs2( int u, int t ) {top[u] = t, id[dfn[u] = ++ cnt] = u;if( son[u] ) dfs2( son[u], t );else return;for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i].first;if( v == f[u] or v == son[u] ) continue;else dfs2( v, v );}}void modify( int x, int y ) {while( top[x] ) {SGT :: modify( 1, 1, n, dfn[top[x]], dfn[x], y );x = f[top[x]];}}int query( int x ) {int ans = 0;while( top[x] ) {ans += SGT :: query( 1, 1, n, dfn[top[x]], dfn[x] );x = f[top[x]];}return ans;}
}signed main() {scanf( "%lld %lld", &n, &Q );for( int i = 1, u, v, w;i < n;i ++ ) {scanf( "%lld %lld %lld", &u, &v, &w );G[u].push_back( make_pair( v, w ) );G[v].push_back( make_pair( u, w ) );}Qtree :: dfs1( 1, 0 );Qtree :: dfs2( 1, 1 );SGT :: build( 1, 1, n );int x, y, sum1 = 0, sum2 = 0;while( Q -- ) {scanf( "%lld %lld", &x, &y );Qtree :: modify( x, y );sum1 += dep[x] * y;sum2 += y;int p = SGT :: query( sum2 + 1 >> 1 );printf( "%lld\n", sum1 + dep[p] * sum2 - (Qtree :: query( p ) << 1) );}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316424.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

巧用linux版powershell,管理linux下的docker

owershell,docker,cli,命令,docker ps,docker image第一章 在linux中搭建docker环境目的&#xff1a;在任意版本的linux&#xff08;物理机&#xff0c;虚拟机&#xff0c;节点机&#xff09;中&#xff0c;安装docker服务。动作&#xff1a;教程略&#xff0c;不是本文主要目的…

P1972 [SDOI2009]HH的项链

P1972 [SDOI2009]HH的项链 题意&#xff1a; 给你一个序列&#xff0c;问这个序列中的种类数 n,m,ai<1e6 题解&#xff1a; 三个方法&#xff1a;莫队(会超时)&#xff0c;树状数组&#xff0c;主席树(会超时) 莫队就是裸题&#xff0c;不讲了&#xff0c;复杂度O(n*sq…

从ASP.NET Core2.2到3.0你可能会遇到这些问题

趁着假期的时间所以想重新学习下微软的官方文档来巩固下基础知识。我们都知道微软目前已经发布了.NET Core3.0的第三个预览版&#xff0c;同时我家里的电脑也安装了vs2019。So&#xff0c;就用vs2019.NET Core3.0来跟着做一下Contoso University这个WEB应用&#xff0c;但是在基…

【学习笔记】整体二分

文章目录引整体二分几道模板题Dynamic Rankings[ZJOI2013]K大数查询[国家集训队]矩阵乘法[THUPC2017] 天天爱射击[CTSC2018]混合果汁引 例1. 给定 nnn 个数 aia_iai​&#xff0c;一次询问&#xff0c;询问区间 [l,r][l,r][l,r] 中的第 kkk 小数。 我们通常想到二分答案&#x…

P2157 [SDOI2009]学校食堂

P2157 [SDOI2009]学校食堂 题意&#xff1a; 小F 的学校在城市的一个偏僻角落&#xff0c;所有学生都只好在学校吃饭。学校有一个食堂&#xff0c;虽然简陋&#xff0c;但食堂大厨总能做出让同学们满意的菜肴。当然&#xff0c;不同的人口味也不一定相同&#xff0c;但每个人…

EntityFramework Core 3.0 Preview

前段时间.Net Core 3.0 发布了&#xff0c;Entity Framework Core 3.0 也发布了Preview版。假期用了一上午大致研究了一遍&#xff0c;同时又体验了一把Visual Studio 2019。总结一下分享给大家&#xff1a;VS2019 新建.Net Core 3.0 Console应用&#xff0c;添加EFCore相关的N…

[luogu-P4299] 首都(并查集 + LCT动态维护树的重心 / 维护虚儿子信息)

problem luogu-P4299 solution 本题考察了很经典的模型&#xff0c;运用了很经典的解法。 本题用到了重心的两个性质&#xff1a; 两棵树合并为同一棵树时&#xff0c;新的重心一定在原来两棵树各自重心的路径上。 重心为根时的最大子树大小最小&#xff0c;不超过 siz/2s…

计算几何模板中的代码

计算几何模板代码选自kuangbin 7 计算几何 7.1 二维几何 // 计算几何模板 const double eps 1e-8; const double inf 1e20; const double pi acos(-1.0); const int maxp 1010; //Compares a double to zero int sgn(double x){if(fabs(x) < eps)return 0;if(x < …

机器学习 ML.NET 发布 1.0 RC

ML.NET 是面向.NET开发人员的开源和跨平台机器学习框架&#xff08;Windows&#xff0c;Linux&#xff0c;macOS&#xff09;,通过使用ML.NET,.NET开发人员可以利用他们现有的工具和技能组&#xff0c;为情感分析&#xff0c;推荐&#xff0c;图像分类等常见场景创建自定义机器…

[PA2015]Siano(线段树 + 二分)

problem luogu-P5579 solution 此题关键在于发现一个结论&#xff1a;生长速度快的草在任何时刻都不可能矮于生长速度慢的草。 正确性显然。 所以当我们将草按照 aaa 升序排序后&#xff0c;每次收割的草一定是一个后缀。 那么这个后缀的起点就可以二分找到。 割完后要对…

容器化时代我们应当选择Kubernetes

昨天发的文章《基于Kubernetes 构建.NET Core 的技术体系》&#xff0c;有同学问.NET Core上有Spring Cloud类似的平台吗&#xff1f; .NET Core出现这么久了&#xff0c;这个为云原生应用开发而准备的系统需要Spring cloud这样的全家桶吗&#xff1f; 大家希望使用Spring Clou…

2021杭电第8场

2021杭电第8场 题号题目知识点HDU 7056X-liked CountingHDU 7057Buying SnacksHDU 7058Ink on paperHDU 7059Counting StarsHDU 7060Separated NumberHDU 7061GCD GameHDU 7062A Simple ProblemHDU 7063Square CardHDU 7064Singing SuperstarHDU 7065Yinyang

[ZJOI2015]幻想乡 Wi-Fi 搭建计划(dp + 结论)

problem luogu-P3344 solution 这个题面&#xff0c;这个数据范围&#xff0c;完完全全就是网络流宗教。。然而我发现建不出来。 很多一眼网络流最后却不是网络流而往往是 dpdpdp 的题目都有一个特性&#xff1a;一个点可以流出多条流量&#xff0c;流入流量却只能为 111。…

CefSharp中c#和JavaScript交互读取电脑信息

介绍CEF是由Marshall Greenblatt于2008年创建的基于Google Chromium的BSD许可开源项目。与主要关注谷歌Chrome应用程序开发的Chromium项目本身不同&#xff0c;CEF专注于在第三方应用程序中促进嵌入式浏览器用例。CEF通过提供生产质量稳定的API&#xff0c;发布跟踪特定Chromiu…

Ink on paper HDU - 7058

Ink on paper HDU - 7058 题意&#xff1a; 给出n个墨水的初始位置&#xff0c;每秒向外扩展0.5cm&#xff0c;显示一个圆圈&#xff0c;问所有墨水连接起来需要多长时间 题解&#xff1a; 很明显&#xff0c;在完全图中找最小生成树&#xff0c;并记录最小生成树中最长的边…

加与乘(博弈论)

problem A,BA,BA,B 在玩游戏&#xff0c;给定一排长度为 nnn 的数列&#xff0c;每个人轮流取出任意一对相邻的两个数&#xff0c;然后把两个数的和或者乘积放入。 TTT 组询问。每组给定 n,mn,mn,m&#xff0c;接下来给定长度为 nnn 的数列 aia_iai​。 m0m0m0 AAA 先操作&…

C#8.0可空引用类型的使用注意要点

最近VS2019正式版发布了&#xff0c;装下来顺便试用了一下C#8.0&#xff0c;最大的看点应该就是可空引用类型了。不过C#8.0仍然处于Beta的状态&#xff0c;而且试用时也遇到了几个坑。背景知识说明&#xff1a;所谓的可空引用类型是指&#xff0c;一旦启用了可空引用类型这个新…

Singing Superstar HDU - 7064

Singing Superstar HDU - 7064 题意&#xff1a; 问在串T中出现了几次不相交的串S&#xff1f; 每次有n个串S询问 题解&#xff1a; AC自动机板子题。。 直接上模板 代码&#xff1a; #include <bits/stdc.h> #include <unordered_map> #define debug(a, b) …

ASP.NET Core Web 项目文件介绍

ASP.NET Core Web 项目文件在本视频中&#xff0c;我们将探索并了解asp.net core项目文件。 我们使用C&#xff03;作为编程语言&#xff0c;因此项目文件具有.csproj扩展名。如果您使用过以前版本的ASP.NET&#xff0c;那么您可能对此文件非常熟悉&#xff0c;但此文件中包含的…

[ZJOI2016] 小星星(树型dp + 状压dp + 容斥)

problem luogu-P3349 solution 这个数据首先就能想到状压 dpdpdp。 先考虑在树上的朴素 dp(i,j,S):dp(i,j,S):dp(i,j,S): 节点 iii 的对应原图编号为 jjj&#xff0c;其子树对应的编号构成的点集为 SSS 的方案数。 需要满足两个限制条件&#xff1a; 原图的每个节点只能被…