首页 > 其他分享 >CF1998E2 Eliminating Balls With Merging (Hard Version)

CF1998E2 Eliminating Balls With Merging (Hard Version)

时间:2024-09-02 17:04:04浏览次数:10  
标签:Balls log ch 最大值 Hard 扩展 mid Version minr

原题链接

考虑对于每个 \(i\),算出向左扩展到 \(1\) 时向右至少和至多扩展到哪里,记为 \(minr\) 和 \(maxr\)。

那么也就是说每个 \(i\) 会对 \(minr\sim maxr\) 做出贡献,差分一下就可以了。重点是怎么计算这两个东西。

先说 \(maxr\)。如果暴力跳,过程是:先向左扩展直到不能扩展,然后再向右扩展到不能扩展。不断重复直到左边界到 \(1\) 或者两边都无法继续扩展宣告失败。

然后你想起了刚刚做完的 E1,每次扩展一定是找到一个最近的最大值,把最大值之前的都加上,再看看能不能也把这个最大值也加上。这个可以用 ST 表和二分 \(\mathcal{O}(\log V\log n)\) 解决。

具体地说,记 \(l,r\) 为当前左右边界,\(s\) 为前缀和,在向左扩展时,要找到一个最大的 \(x\) 使得 \(s_r-s_{l-1}<a_{l-1}\),移项变为 \(s_r<a_{l-1}+s_{l-1}\),用 ST 表维护 \(a_i+s_i\) 的最大值。二分时每次检查右区间是否符合条件,如果是则增大左边界,否则减小右边界。向右扩展基本同理,式子稍有变化,换成了维护最小值。

其实 \(maxr\) 也可以双指针来着然后再看 \(minr\)。有区别的是向右扩展时不是无脑扩展,而是扩展到刚好够左边能跨过下一个最大值。那么只需每次向右扩展之后再二分一下,尝试把 \(r\) 往回减一些。这个不需要 ST 表。

来看一下时间复杂度。每次当前区间总和因为跨过了一个最大值,所以至少增加了一倍,那么也就最多增加 \(\log V\) 次。再加上二分和枚举 \(i\) 的复杂度,总复杂度 \(\mathcal{O}(n\log n\log V)\)。

细节说多不多说少不少。

#include<bits/stdc++.h>
#define int long long
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
using namespace std;
const int N=2e5+5;
const int inf=0x3f3f3f3f;
inline int read();
int n,m,k;int a[N];
int f[30][N],g[30][N];
int ans[N],minr[N],maxr[N],s[N];
int getmax(int x,int y){
	int s=__lg(y-x+1);
	return max(f[s][x],f[s][y-(1<<s)+1]);
}
int getmin(int x,int y){
	int s=__lg(y-x+1);
	return min(g[s][x],g[s][y-(1<<s)+1]);
}
void work(){
	n=read();read();
	FOR(i,1,n)a[i]=read(),s[i]=s[i-1]+a[i],ans[i]=0;
	a[n+1]=0;
	FOR(i,1,n)f[0][i]=a[i]+s[i],g[0][i]=s[i]-a[i+1];
	for(int j=1;1<<j<=n;++j)
		for(int i=1;i+(1<<j)-1<=n;++i){
			f[j][i]=max(f[j-1][i],f[j-1][i+(1<<j-1)]);
			g[j][i]=min(g[j-1][i],g[j-1][i+(1<<j-1)]);
		}
	int L,R,l,r,mid;
	FOR(i,1,n){
		l=i,r=i;
		while(1){
			bool flag=0;
			L=1,R=l;
			while(L<R){
				mid=L+R>>1;
				if(s[r]<getmax(mid,R-1))L=mid+1;
				else R=mid;
			}
			if(l!=L)l=L,flag=1;
			if(l==1||r==n)break;
			L=r,R=n;
			while(L<R){
				mid=L+R>>1;
				if(getmin(L,mid)<s[l-1])R=mid;
				else L=mid+1;
			}
			if(r!=L){
				flag=1;
				int x=L;
				L=r+1,R=x;
				while(L<R){
					mid=L+R>>1;
					if(s[mid]-s[l-1]>=a[l-1])R=mid;
					else L=mid+1;
				}
				r=R;
			}
			if(!flag)break;
		}
		if(l==1)minr[i]=r;
		else minr[i]=inf;
		l=i,r=i;
		while(1){
			bool flag=0;
			L=r,R=n;
			while(L<R){
				mid=L+R>>1;
				if(getmin(L,mid)<s[l-1])R=mid;
				else L=mid+1;
			}
			if(r!=L)flag=1,r=R;
			L=1,R=l;
			while(L<R){
				mid=L+R>>1;
				if(s[r]<getmax(mid,R-1))L=mid+1;
				else R=mid;
			}
			if(l!=L)l=L,flag=1;
			if(!flag)break;
		}
		if(l==1)maxr[i]=r;
		else maxr[i]=inf;
	}
	FOR(i,1,n)
		if(maxr[i]!=inf&&minr[i]<=maxr[i])
			ans[minr[i]]++,ans[maxr[i]+1]--;
	FOR(i,1,n)ans[i]+=ans[i-1];
	FOR(i,1,n)printf("%lld ",ans[i]);puts("");
}
signed main()
{
	int T=read();
	while(T--)work();
	return 0;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return f*x;
}

标签:Balls,log,ch,最大值,Hard,扩展,mid,Version,minr
From: https://www.cnblogs.com/LHLeisus/p/18393071

相关文章

  • CF 2002 D1. DFS Checker (Easy Version) (*1900)思维
    CF2002D1.DFSChecker(EasyVersion)(*1900)思维题目链接题意:给你一棵\(n\)个节点组成的完全二叉树,并给出一个排列\(p\)。接下来进行\(q\)次询问。每次询问给你\(x\)和\(y\),你需要交换\(p_x\)和\(p_y\)。并且回答交换之后的排列\(p\)是否是这棵完全二叉树......
  • ShardingSphere-JDBC实现数据加解密
    一、什么是ShardingSphere?        ShardingSphere定位为轻量级Java框架,在Java的JDBC层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。ApacheShardingSphere旨......
  • Apache顶级项目ShardingSphere — SQL Parser的设计与实现
    导语:SQL作为现代计算机行业的数据处理事实标准,是目前最重要的数据处理接口之一,从传统的DBMS(如MySQL、Oracle),到主流的计算框架(如spark,flink)都提供了SQL的解析引擎,因此想对sql进行精细化的操作,一定离不开SQLParser。ApacheShardingSphere是一套开源的分布式数据库中间件解决方......
  • 对比 Vitess,ShardingSphere 有哪些不同
    本篇为InfoQ中文站供稿原文链接:https://www.infoq.cn/article/NHSAAmN*MfpLiTiTTEu5?from=timeline&isappinstalled=0ShardingSphere是什么?ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(规......
  • Apache顶级项目ShardingSphere — SQL Parser的设计与实现
    导语:SQL作为现代计算机行业的数据处理事实标准,是目前最重要的数据处理接口之一,从传统的DBMS(如MySQL、Oracle),到主流的计算框架(如spark,flink)都提供了SQL的解析引擎,因此想对sql进行精细化的操作,一定离不开SQLParser。ApacheShardingSphere是一套开源的分布式数据库中间件解决方案......
  • 对比 Vitess,ShardingSphere 有哪些不同
    本篇为InfoQ中文站供稿原文链接:https://www.infoq.cn/article/NHSAAmN*MfpLiTiTTEu5?from=timeline&isappinstalled=0ShardingSphere是什么?ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(规划中)这3......
  • 内核模块踩内存问题定位利器- hardware breakpoint
    内核由于共享内存地址空间,如果没有合适的工具,很多踩内存的问题即使复现,也无法快速定位;在新的内核版本中引入了一个新工具hardwarebreakpoint,其能够监视对指定的地址的特定类型(读/写)的数据访问,有利于该类问题的定位;以下是一个使用该工具的例子(来自内核代码linux-3.10/sampl......
  • Atcoder [AGC006D] Median Pyramid Hard 题解 [ 紫 ] [ 二分 ] [ adhoc ]
    MedianPyramidHard:二分trick加上性质观察题。trick我们可以二分值域,然后把大于等于它的数标记成\(1\),其他标记为\(0\)(有些题需要标记成\(-1\)),然后根据这个来check方案是否可行,这通常通过判断某个数是否是\(1\)来实现。本质上其实就是check大于等于它的数能否成为......
  • 使用Hardhat的forking功能在本地模拟EVM链真实环境
    HardhatNetwork可以复制主网区块链状态数据到本地环境,包括所有余额和部署的合约。称为forkingmainnet,可以使得本地测试模拟主网环境,但不用gas,所做的交易也不会真的发生在主网。不止以太坊主网,其他兼容EVM的区块链都可以fork。我们来看一下如何使用这个重要功能。如下例子,是如何......
  • Java后端微服务架构下的数据库分库分表:Sharding-Sphere
    Java后端微服务架构下的数据库分库分表:Sharding-Sphere大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!随着微服务架构的广泛应用,数据库层面的扩展性问题逐渐凸显。Sharding-Sphere作为一个分布式数据库中间件,提供了数据库分库分表的能力,帮助开发者解......