|
Problem Description
For a number sequence A, there are several queries. For each query, it is required to find a non-empty continuous segment in sequence A so that the absolute value of the sum of the segments is as close as possible to P.
Input format
The first line has two numbers N and T, which indicate the length of the sequence and the number of queries.
The next line contains N integers, representing the A sequence. Next, in line T, a number P per line indicates a query.
Output format
A total of T lines are output, each line corresponds to an answer to a query.
Output of three numbers: the first number is the closest to P that can be achieved, and the last two numbers L and R indicate that the number of L to R in A sequence can achieve this answer.
If there are multiple solutions, the output L is the smallest solution.
If there are multiple solutions, output the solution with the smallest R.
sample input
Input Sample 1
5 1
-10 -5 0 5 10
3
Sample input 2
6 2
-2 5 3 0 -3 -4
1
6
Sample input 3
7 2
-2 -1 -2 4 1 -3 7
0
6
sample output
Sample output 1
5 2 2
Sample output 2
1 1 6
6 1 3
Sample output 3
0 1 5
6 2 7
Tips
[Data Scope]
30% of the data is 1<=N<=1,000.
60% of the data is 1<=N<=10,000.
100% data 1 <=N<=100,000, absolute value of numbers in A sequence <=10,000, T<=100, inquiry number <=10^9
Satisfies | sum [j] - sum [i-1] | >= P or | sum [j] - sum [i-1] | <= p
I remember my boss saying that absolute values can be turned on.
Open and change shape
Sum [j] + P <= sum [i-1];
Or sum [j]-p<=sum [i-1];
At this point, we can reproduce the sum array to the struct sum2 array as follows
val values are sorted, of course, the replicated id should be preserved, that is, we need to sort the replicated struct structure array
Then copy the va value of the array to the sum3 array
Then enumerate N with j
Next, binary pairs sum[j]-p and sum[j]+p look for the minimum value of >= in the sum3 array
The id is recorded in the structure of sum2 and the subscripts of sum3 and sum2 are the same.
ans=min{abs(abs(sum3 [binary subscript] - sum[j] (- or +) p)}
{
r=j;
l=sum2 [enumerated subscript]. ID + 1; / if (ans > ABS (abs (sum3 [subscript] - sum[j]) (+/-) p))
}
if(ans==abs(abs(sum3 [subscript]-sum [j]-/+p))
{
if(l==sum2 [subscript]. ID + 1 & & R > j)
{
l=sum2 [subscript]. id+1;
r=j;
}
If (l > sum2 [subscript]. id+1)
{
l=sum2 [subscript]. id+1;
r=j;
}
}
Then cout
// #include<bits/stdc++.h> using namespace std; #define maxnn 102000 #define ll long long ll sum[maxnn]; ll sum3[maxnn]; ll n,t; struct node { ll id,va; }sum1[maxnn]; bool cmp(node a,node b) { if(a.va==b.va) return a.id<b.id; else return a.va<b.va; } int main() { cin>>n>>t; ll x; ll uu; ll p; ll ans=1000000000000; sum1[0].id=0; sum1[0].va=0; for(int i=1;i<=n;i++) { scanf("%lld",&x); sum[i]=sum[i-1]+x; sum1[i].va=sum[i]; sum1[i].id=i; } sort(sum1,sum1+1+n,cmp); for(int i=0;i<=n;i++) { sum3[i]=sum1[i].va; } for(int i=1;i<=t;i++) { ans=100000000000; ll l=10000000000,r=10000000000; cin>>p; for(int j=1;j<=n;j++) { int xx=lower_bound(sum3,sum3+1+n,sum[j]+p)-sum3;//j int xxx=lower_bound(sum3,sum3+1+n,sum[j]-p)-sum3; if(ans>abs(abs(sum3[xx]-sum[j])-p)) { uu=abs(sum3[xx]-sum[j]); ans=abs(abs(sum3[xx]-sum[j])-p); r=j; l=sum1[xx].id+1; } if(ans==abs(abs(sum3[xx]-sum[j])-p)) { if(l==sum1[xx].id+1&&r>j) { l=sum1[xx].id+1; r=j; } if(l>sum1[xx].id+1) { l=sum1[xx].id+1; r=j; } } if(ans>abs(abs(sum3[xxx]-sum[j])-p)) { uu=abs(sum3[xxx]-sum[j]); ans=abs(abs(sum3[xxx]-sum[j])-p); r=j; l=sum1[xxx].id+1; } if(ans==abs(abs(sum3[xxx]-sum[j])-p)) { if(l==sum1[xxx].id+1&&r>j) { l=sum1[xxx].id+1; r=j; } if(l>sum1[xxx].id+1) { l=sum1[xxx].id+1; r=j; } } } cout<<uu<<" "<<l<<" "<<r<<endl; } }
Monotonic queue
#include<stdio.h> #include<algorithm> #include<deque> #include<iostream> #define MAXN 100005 using 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(); } }