CF765F Souvenirs(势能线段树)

CF765F Souvenirs

  • problem
  • solution
  • code

problem

题目链接

solution

这个势能线段树简直是太巧妙了!!!( ఠൠఠ )ノ

将询问按右端点升序离线下来。

对于每一个右端点 rrr,维护 ansi=min⁡{∣ai−aj∣,j∈[i,r]}ans_i=\min\{|a_i-a_j|,j\in[i,r]\}ansi=min{aiaj,j[i,r]}

用线段树查询区间 [l,r][l,r][l,r] 内的 min⁡{ansi,i∈[l,r]}\min\{ans_i,i\in[l,r]\}min{ansi,i[l,r]} 就是答案了。

时间复杂度的瓶颈在于修改维护线段树上面。暴力做是 O(n2)O(n^2)O(n2) 的。

考虑优化。假设 ansians_iansi 的最优选择点在 jjj

在这里插入图片描述

  • 如果 ara_rar 是在黄色点,即 <ai+aj2<\frac{a_i+a_j}{2}<2ai+aj ,这个时候要必须更新 ansians_iansi。这会让 ansians_iansi 的值变小至少一半。

  • 如果 ara_rar 是在蓝色点,即 >ai+aj2>\frac{a_i+a_j}{2}>2ai+aj,这个时候直接更新 ansjans_jansj 而不再更新 ansians_iansi

    因为 j>i∧ansj<ansij>i\wedge ans_j<ans_ij>iansj<ansi ,最后 rrr 的询问肯定答案是不会选到 ansians_iansi 的。

    所以就算 ansians_iansi 是错的,也不影响!

  • 如果 ara_raraia_iai 等值线下面,也是一样的。

ansians_iansi 看作势能,递减到 000 时就不再更新。每次更新至少减少一半。

所以修改点数应该是 nlog⁡an\log anloga 的。

具体而言:先修改右区间,再修改左区间。且如果当前修改的答案不如之前更新的答案,就直接跳过即可。同时需要存储下区间内所有的 aaa

这样实际操作的只有必须更新的点。

总时间复杂度为:O(nlog⁡nlog⁡a)O(n\log n\log a)O(nlognloga)

code

#include <vector>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 400005
#define inf 0x7f7f7f7f
vector < int > G[maxn];
struct node { int l, r, id; }q[maxn];
int n, Q;
int a[maxn], ans[maxn];namespace SegMentTree {int ans = inf;int Min[maxn];#define lson now << 1#define rson now << 1 | 1void build( int now, int l, int r ) {Min[now] = inf;for( int i = l;i <= r;i ++ ) G[now].push_back( a[i] );sort( G[now].begin(), G[now].end() );if( l == r ) return;int mid = ( l + r ) >> 1;build( lson, l, mid );build( rson, mid + 1, r );}/*void modify( int now, int l, int r, int R, int x ) {if( R < l ) return;if( r <= R ) {auto it = lower_bound( G[now].begin(), G[now].end(), x );if( it != G[now].end() ) Min[now] = min( Min[now], (*it) - x );if( it != G[now].begin() ) Min[now] = min( Min[now], x - *(it - 1) );if( Min[now] >= ans ) return;}if( l == r ) { ans = min( ans, Min[now] ); return; }int mid = ( l + r ) >> 1;modify( rson, mid + 1, r, R, x ); //优先更新最近的点modify( lson, l, mid, R, x );Min[now] = min( Min[lson], Min[rson] );ans = min( ans, Min[now] );}*/void modify( int now, int l, int r, int R, int x ) {if( R < l ) return;if( r <= R ) {it = lower_bound( G[now].begin(), G[now].end(), x );int tmp = inf;if( it != G[now].end() ) tmp = *it - x;if( it != G[now].begin() ) it--, tmp = min( tmp, x - *it );Min[now] = min( Min[now], tmp );if( tmp >= ans ) return;}if( l == r ) { ans = min( ans, Min[now] ); return; }modify( rson, mid + 1, r, R, x );ans = min( ans, Min[rson] );modify( lson, l, mid, R, x );Min[now] = min( Min[lson], Min[rson] );ans = min( ans, Min[now] );}int query( int now, int l, int r, int L ) {if( r < L ) return inf;if( L <= l ) return Min[now];int mid = ( l + r ) >> 1;return min( query( lson, l, mid, L ), query( rson, mid + 1, r, L ) );}}int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ ) scanf( "%d", &a[i] );scanf( "%d", &Q );for( int i = 1;i <= Q;i ++ ) scanf( "%d %d", &q[i].l, &q[i].r ), q[i].id = i;SegMentTree :: build( 1, 1, n );sort( q + 1, q + Q + 1, []( node x, node y ) { return x.r < y.r; } );int ip = 1;while( q[ip].r <= 1 ) ip ++;for( int i = 2;i <= n;i ++ ) {SegMentTree :: ans = inf;SegMentTree :: modify( 1, 1, n, i - 1, a[i] );while( q[ip].r == i )ans[q[ip].id] = SegMentTree :: query( 1, 1, n, q[ip].l ), ip ++;}for( int i = 1;i <= Q;i ++ ) printf( "%d\n", ans[i] );return 0;
}

Upd:感谢评论区的 hack\text{hack}hack 数据让我发现自己的代码写得有点问题。
和小同志研究了一天发现是代码注释部分的问题。
大概就是,当前 iii 插入时,按照分析应该是遇到更优秀 jjj 就不再往左子树找了。
这个更优秀是和以前存的答案比较。
但是之前代码实现是和现在被覆盖的答案比较。势能就差得离谱。
现在新代码在叶子节点时输出访问次数就大概是 111

但是。。。呃呃呃呃,现在这份代码加上读优跑评论区的数据最快也要 5s5s5s。。。
我们讨论了一下我这份代码的写法,更偏向 nlog⁡n2log⁡Vn\log n^2\log Vnlogn2logV 的时间复杂度,因为要走 log⁡n\log nlogn 层线段树,每层内还有个 vector\text{vector}vector 的二分。
可能把二分写在外面能少个 log\text{log}log 的嵌套。
但是跑评论区的数据每个点都只被访问了一次,时间复杂度我就不是很懂了?。

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

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

相关文章

AcWing 220. 最大公约数

AcWing 220. 最大公约数 题意&#xff1a; 题解&#xff1a; 题目就变成了AcWing 201. 可见的点 当然有微调&#xff0c;因为可见的点里面是从0开始&#xff0c;本题从1开始&#xff0c;所以本题中phi[1]认为是0 AcWing 201. 可见的点的题解 代码&#xff1a; #include<b…

欧拉函数(简单介绍+例题)

Acwing视频讲解 欧拉函数&#xff1a;正整数n&#xff0c;欧拉函数是小于n的正整数中与n互质的数的数目 Np1a1 * p1a2 * p1a3 * …* p1ak 如果pj是i的最小质因子 红色区域一样 经推导得&#xff1a;phi[i * pj] phi[i] * pj 如果pj不是i的最小质因子 经推导&#xff1a;phi[…

程序员过关斩将--你的面向接口编程一定对吗?

菜菜哥&#xff0c;出大事啦怎么了&#xff0c;你和男票分手了&#xff1f;很正常&#xff0c;谁让你男票是产经经理呢不是啦&#xff0c;是我做的一个小游戏&#xff0c;需求又变了&#xff0c;程序我快改不动了说来让我欢乐一下&#xff1f;菜菜哥&#xff0c;咱两还能不能好…

Codeforces:779(div2)

前言 solve 4 rnk247 占了罚时的便宜。 CF不占罚时便宜就会被罚时占便宜 感觉这场似乎都是性质题&#xff0c;一眼看出性质就秒了&#xff0c;看不出就很难做出来了。 C似乎卡了很多人。但我做起来还好。 D2做不出来有些懊恼。 E是妙题。 题目 A 水题&#xff0c;保证male…

我们为什么要搞长沙.NET技术社区(4)

我们为什么要搞长沙.NET技术社区&#xff08;4&#xff09;邹溪源&#xff0c;2019年3月7日Ps:文中的.NET 包括且不限定于传统.NET Framework技术和.NET Core技术。1. 楔子昨天&#xff08;2019年3月6日&#xff09;晚餐时间&#xff0c;有幸得到长沙技术圈资深.NET开发者出生…

P1290 欧几里德的游戏

P1290 欧几里德的游戏 题意&#xff1a; 给定两个正整数 M 和 N&#xff0c;从 Stan 开始&#xff0c;从其中较大的一个数&#xff0c;减去较小的数的正整数倍&#xff0c;当然&#xff0c;得到的数不能小于 0。然后是 Ollie进行同样的操作&#xff0c;直到一个人得到0&#…

C#机器学习之判断日报是否合格

原文作者&#xff1a;心莱科技肖鑫简单来说机器学习的核心步骤在于“获取学习数据&#xff1b;选择机器算法&#xff1b;定型模型&#xff1b;评估模型&#xff0c;预测模型结果”&#xff0c;下面本人就以判断日报内容是否合格为例为大家简单的阐述一下C#的机器学习。第一步&a…

SignalR2结合ujtopo实现拓扑图动态变化

上一篇文章基于jTopo的拓扑图设计工具库ujtopo&#xff0c;介绍了拓扑设计工具&#xff0c;这一篇我们使用SignalR2结合ujtopo实现拓扑图的动态变化。仅仅作为演示&#xff0c;之前的文章SignalR2简易数据看板演示&#xff0c;用一个小的示例演示了SignalR作为数据看板的用法&a…

Ocelot 入门Demo系列(01-Ocelot极简单Demo及负载均衡的配置)

来源&#xff1a;https://www.cnblogs.com/7tiny/p/10493805.html【前言】Ocelot是一个用.NET Core实现并且开源的API网关&#xff0c;它功能强大&#xff0c;包括了&#xff1a;路由、请求聚合、服务发现、认证、鉴权、限流熔断、并内置了负载均衡器与Service Fabric、Butterf…

博弈论(基础概念+例题)

博弈论(b站视频) 文章目录一些概念以Nim游戏为例Nim游戏介绍定义 必败/必胜局面必败/必胜局面的判定引理Nim游戏判定引理的等价命题有向图游戏对判定引理的数学描述-Sg函数有向图游戏的和题目&#xff1a;[有向图游戏][有向图游戏的和][构造/转化类]一些概念 以Nim游戏为例 Ni…

.NET Core 3.0 linux 部署小贴士

dotnet core 3.0 目前还是测试版&#xff0c;在linux下安装 sdk 需要有一些注意事项1.下载urlhttps://dotnet.microsoft.com/download/thank-you/dotnet-sdk-3.0.100-preview-009812-linux-x64-binaries2.安装指令mkdir -p $HOME/dotnet && tar zxf dotnet-sdk-3.0.100…

PuppeteerSharp: 更友好的 Headless Chrome C# API

前端就有了对 headless 浏览器的需求&#xff0c;最多的应用场景有两个UI 自动化测试&#xff1a;摆脱手工浏览点击页面确认功能模式爬虫&#xff1a;解决页面内容异步加载等问题也就有了很多杰出的实现&#xff0c;前端经常使用的莫过于 PhantomJS 和 selenium-webdriver&…

中国.NET:东莞+长沙.NET俱乐部现场花絮及合肥、苏州、上海等地活动预

《传承有序》与微软技术的发展历程相似&#xff0c;微软俱乐部的发展经历着沉沉浮浮&#xff0c;曾经随着微软走向封闭与固执&#xff0c;.NET社区年轻一代的声音被忽略&#xff0c;.NET社区后继无人。社区的沉默是可怕的&#xff0c;很多社区沉寂消亡。但是在2018年&#xff0…

【AcWing 235. 魔法珠

【AcWing 235. 魔法珠 题意&#xff1a; 有n堆魔法珠&#xff0c;第i堆有ai个&#xff0c;两个人轮流进行以下操作&#xff1a; 当轮到某人操作时&#xff0c;如果每堆中魔法珠的数量均为 1&#xff0c;那么他就输了。 问谁赢谁输 题解&#xff1a; 经典博弈论问题 注意本…

Abp vNext 切换MySql数据库

Abp vNext是Abp的下一代版本&#xff0c;目前还在经一步完善&#xff0c;代码已经全部重写了&#xff0c;好的东西保留了下来&#xff0c;去除了很多笨重的东西&#xff0c;从官宣来看&#xff0c;Abp vNext主要是为了以后微服务架构而诞生的。从源码来看&#xff0c;Abp vNext…

采用.NET CORE的全异步模式打造一款免费的内网穿透工具--NSmartProxy

什么是NSmartProxy&#xff1f;NSmartProxy是一款免费的内网穿透工具。特点跨平台&#xff0c;客户端和服务端均可运行在MacOS&#xff0c;Linux&#xff0c;Windows系统上&#xff1b;使用方便&#xff0c;配置简单&#xff1b;多端映射&#xff0c;一个NSmart Proxy客户端可以…

Acwing 236. 格鲁吉亚和鲍勃(博弈论妙题)

Acwing 236. 格鲁吉亚和鲍勃 题意&#xff1a; 一排网格&#xff0c;将网格从左到右依次编号 1,2,3&#xff0c;…&#xff0c;并将 N 个西洋棋棋子放在不同的网格上&#xff0c;如下图所示&#xff1a; 两个人轮流移动棋子 每次玩家选择一个棋子&#xff0c;并将其向左移动…

.NET Core 跨平台 串口通讯 ,Windows/Linux 串口通讯

1&#xff0c;前言开发环境&#xff1a;在 Visual Studio 2017&#xff0c;.NET Core 2.x串口通讯用于设备之间&#xff0c;传递数据&#xff0c;物联网设备中广泛使用串口方式连接通讯&#xff0c;物联网通讯协议 &#xff1a;Modbus 协议 ASCII、RTU、TCP模式是应用层的协议&…

Game of Cards Gym - 102822G

Game of Cards Gym - 102822G 题意&#xff1a; 小兔子和小马喜欢玩奇怪的纸牌游戏。现在&#xff0c;他们正在玩一种叫做0123游戏的纸牌游戏。桌子上有几张牌。其中c0标记为0&#xff0c;c1标记为1&#xff0c;c2标记为2&#xff0c;c3标记为3。小兔子和小马轮流玩游戏&…

开源组件ExcelReport 3.x.x 使用手册(为.netcore而来

ExcelReport转眼已经开源4年了&#xff0c;期间有很长时间也停止了对它的维护。18年年末有人联系到我&#xff0c;说“兄弟&#xff0c;ExcelReport不错&#xff0c;但什么时候支持.netcore呢&#xff1f;”。我寥寥的回了几句搪塞的话&#xff0c;也没当回事。后来这兄弟又来问…