当前位置: 首页 > news >正文

[CF407E]k-d-sequence

题意:给定$a_{1\cdots n}$,让你求出一个最长的子串$a_{l\cdots r}$,使得这个子串加上最多$k$个数字并排序后是一个公差为$d$的等差数列

首先$d=0$就是最长连续相等段,扫一遍解决

然后显然$a_{l\cdots r}$都是模$d$同余的,我们不妨对模$d$的余数不同的段分开处理

把每个数先$+10^9$(让它变为非负)再除以$d$,转化为$d=1$的问题

那么题目的限制条件就是$\mathop\max\limits_{i=l}^ra_i-\mathop\min\limits_{i=l}^ra_i+1\leq r-l+1+k$且$a_{l\cdots r}$中没有重复元素

所以整个算法的大致思路就是,对$a_{l\cdots r}$,从大到小枚举$i\in[l,r]$,找到最大的$j\in[l,r]$满足$\mathop\max\limits_{k=i}^ja_k-\mathop\min\limits_{k=i}^ja_k-r\leq k-l$且$a_{i\cdots j}$中没有相同元素

没有相同元素:直接用一个map存每个数上一次出现的位置,相应左移$r$即可

对于这个不等式,注意到$f(r)=\mathop\max\limits_{i=l}^ra_i$是单调不减的,所以我们可以用一个单调栈存当前区间内对于不同的$j$,对上式有贡献的$a_i$(即从左往右扫,会令当前最大值变化的那些$a_i$),$\min$同理,当左端点移动时,入栈出栈的同时用线段树维护$\max-\min$即可,对于$-r$,建线段树时第$i$位的初值赋为$-i$即可,我们只需要在线段树上二分找到最右的$\leq k-i$的值即可

#include<stdio.h>
#include<map>
using namespace std;
int mn[800010],ad[800010];
void add(int x,int v){
	mn[x]+=v;
	ad[x]+=v;
}
void pushdown(int x){
	if(ad[x]){
		add(x<<1,ad[x]);
		add(x<<1|1,ad[x]);
		ad[x]=0;
	}
}
void pushup(int x){mn[x]=min(mn[x<<1],mn[x<<1|1]);}
void build(int l,int r,int x){
	if(l==r){
		mn[x]=-l;
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,x<<1);
	build(mid+1,r,x<<1|1);
	pushup(x);
}
void modify(int L,int R,int v,int l,int r,int x){
	if(L<=l&&r<=R)return add(x,v);
	pushdown(x);
	int mid=(l+r)>>1;
	if(L<=mid)modify(L,R,v,l,mid,x<<1);
	if(mid<R)modify(L,R,v,mid+1,r,x<<1|1);
	pushup(x);
}
int query(int L,int R,int v,int l,int r,int x){
	if(mn[x]>v)return 0;
	if(l==r)return l;
	pushdown(x);
	int mid=(l+r)>>1,res;
	if(R>mid){
		res=query(L,R,v,mid+1,r,x<<1|1);
		if(res)return res;
	}
	if(L<mid){
		res=query(L,R,v,l,mid,x<<1);
		if(res)return res;
	}
	return 0;
}
map<int,int>pos;
int a[200010],s1[200010],s2[200010],n,k,d,t1,t2,L,R;
void solve(int l,int r){
	if(l==r)return;
	int i,tr,res;
	for(i=l;i<=r;i++)a[i]=a[i]/d+1;
	tr=r+1;
	pos.clear();
	t1=t2=0;
	s1[0]=s2[0]=r+1;
	for(i=r;i>=l;i--){
		if(pos.count(a[i]))tr=min(tr,pos[a[i]]);
		while(t1&&a[i]>a[s1[t1]]){
			modify(s1[t1],s1[t1-1]-1,-a[s1[t1]],1,n,1);
			t1--;
		}
		t1++;
		s1[t1]=i;
		modify(s1[t1],s1[t1-1]-1,a[i],1,n,1);
		while(t2&&a[i]<a[s2[t2]]){
			modify(s2[t2],s2[t2-1]-1,a[s2[t2]],1,n,1);
			t2--;
		}
		t2++;
		s2[t2]=i;
		modify(s2[t2],s2[t2-1]-1,-a[i],1,n,1);
		res=query(i,tr-1,k-i,1,n,1);
		if(res-i>R-L||(res-i==R-L&&i<L)){
			L=i;
			R=res;
		}
		pos[a[i]]=i;
	}
}
int main(){
	int i,l,r;
	scanf("%d%d%d",&n,&k,&d);
	for(i=1;i<=n;i++){
		scanf("%d",a+i);
		a[i]+=1000000000;
	}
	L=R=1;
	if(d==0){
		for(l=1;l<=n;l=r){
			for(r=l;r<=n&&a[r]==a[l];r++);
			if(r-l>R-L+1){
				L=l;
				R=r-1;
			}
		}
		printf("%d %d",L,R);
		return 0;
	}
	build(1,n,1);
	L=R=1;
	for(l=1;l<=n;l=r){
		for(r=l;r<=n&&a[l]%d==a[r]%d;r++);
		solve(l,r-1);
	}
	printf("%d %d",L,R);
}

转载于:https://www.cnblogs.com/jefflyy/p/8858672.html

相关文章:

  • 笔记
  • 8、Java并发性和多线程-静态条件与临界区
  • 区块链101:以太智能合同如何运作?
  • 初试Code First(附Demo)
  • 我的面试准备过程--容器(更新中)
  • js中 size和length的区别
  • 【转】mysql锁表解决方法
  • angularjs之filter过滤器
  • 一起来玩AZURE SQL(一)AZURE SQL 介绍
  • 内核线程、轻量级进程、用户线程三种线程概念解惑(线程≠轻量级进程)【转】...
  • 试用友盟SDK实现Android分享微信朋友圈
  • 程序员书单【持续更新】
  • 烂代码传奇
  • Docker的安装和测试
  • React-Native - 收藏集 - 掘金
  • 2017-09-12 前端日报
  • canvas 高仿 Apple Watch 表盘
  • CSS 三角实现
  • Github访问慢解决办法
  • go append函数以及写入
  • Python3爬取英雄联盟英雄皮肤大图
  • Python连接Oracle
  • ReactNativeweexDeviceOne对比
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • Terraform入门 - 1. 安装Terraform
  • 阿里研究院入选中国企业智库系统影响力榜
  • 七牛云假注销小指南
  • 一、python与pycharm的安装
  • 阿里云重庆大学大数据训练营落地分享
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • #git 撤消对文件的更改
  • #if 1...#endif
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .net 4.0发布后不能正常显示图片问题
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .net core 控制台应用程序读取配置文件app.config
  • .Net MVC4 上传大文件,并保存表单
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • ::
  • @Async注解的坑,小心
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚
  • @private @protected @public
  • [CareerCup] 17.8 Contiguous Sequence with Largest Sum 连续子序列之和最大