接近 单调队列
来源:互联网 发布:linux如何设置ss翻墙 编辑:程序博客网 时间:2024/06/08 13:17
NOKJ 3545 接近
问题描述
对于一个数字序列A,并且有若干询问。对于每个询问,要求求出一段在序列A中非空 的连续段使得这一段数字的总和的绝对值尽量接近P。
输入格式
第一行2个数N、T,表示序列的长度和询问的个数。
接下来一行N个整数,表示A序列。 接下来T行,每行一个数P表示询问。
输出格式
共输出T行,每行对应一个询问的答案。
输出3个数:第一个数为能够实现的最接近P 的数,后面两个数L、R表示A序列中的L到 R这一段数能实现这个答案。
如果存在多解,输出L最小的解;
如果还有多解,输出R最小的解。
样例输入
输入样例1
5 1
-10 -5 0 5 10
3
样例输入2
6 2
-2 5 3 0 -3 -4
1
6
样例输入3
7 2
-2 -1 -2 4 1 -3 7
0
6
样例输出
样例输出1
5 2 2
样例输出2
1 1 6
6 1 3
样例输出3
0 1 5
6 2 7
数据范围
30%的数据 1<=N<=1,000。
60%的数据 1<=N<=10,000。
100%的数据 1<=N<=100,000,A 序列中数字绝对值<=10,000,T<=100,询问的 数字<=10^9
由于有多组询问,容易想到两种思路:
1.预处理出所有答案并排序,询问时二分查找;
2.对每次询问都跑一遍。
显然第一种思路是行不通的,预处理出所有区间前缀和之差就是
然而这样就有一个问题:前缀和数组并不满足单调性,这怎么办?
回到问题本身。问题等价于下面的形式:求出一对
不妨将前缀和从大到小排序。对于
满足剩下的条件,注意细节即可。
#include<stdio.h>#include<algorithm>#include<deque>#include<iostream>#define MAXN 100005using namespace std;int N,T,R,L,Ans,P,Delta;struct node{int id,v;}sum[MAXN];bool operator<(node x,node y){if(x.v==y.v)return x.id<y.id;return x.v>y.v;}void Solve(){ Delta=L=R=1e9; deque<int>Q; int i,t,a,b,tmp; for(i=0;i<=N;i++) { while(Q.size()&&sum[Q.front()].v-sum[i].v>=P) { t=Q.front(); tmp=sum[t].v-sum[i].v; a=min(sum[t].id,sum[i].id); b=max(sum[t].id,sum[i].id); if(tmp-P<=Delta) { if(tmp-P==Delta) { if(L>=a) { if(L==a)R=min(R,b); else L=a,R=b; } } else { Ans=tmp; L=a;R=b; } Delta=tmp-P; } Q.pop_front(); } Q.push_back(i); t=Q.front(); tmp=sum[t].v-sum[i].v; a=min(sum[t].id,sum[i].id); b=max(sum[t].id,sum[i].id); if(P-tmp<=Delta&&Q.size()!=1) { if(P-tmp==Delta) { if(L>=a) { if(L==a)R=min(R,b); else L=a,R=b; } } else { Ans=tmp; L=a;R=b; } Delta=P-tmp; } } printf("%d %d %d\n",Ans,L+1,R);}int main(){ int i,x; scanf("%d%d",&N,&T); for(i=1;i<=N;i++) { scanf("%d",&x); sum[i].v=sum[i-1].v+x; sum[i].id=i; } sort(sum,sum+N+1); for(i=1;i<=T;i++) { scanf("%d",&P); Solve(); }}
- 接近 单调队列
- NKOJ 3545 接近(DP+单调队列)
- 单调栈 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- 单调队列
- SPI通讯协议介绍(有见地,学法可取)
- 远程访问VPN Easy VPN --route
- 开启java的进阶之路前言
- 实现OLAP在非税系统的应用的一个方案
- Flask-Script
- 接近 单调队列
- Android TV真机测试
- 2017 10 04 NOIP2014复赛day1
- 17:最好的草
- 基于STM32与NOR FLASH的SPI通信(有见地,学法可取)
- C++一本通题库1002
- 查看Ubuntu安装软件的方法
- 重返数学史的黄金时代,由数学推动诞生的人工智能,一部人类智慧形成的历史
- 学霸女神冯净冰:我是如何从复旦走到诺奖获得者经济学大会的