Bound Found [POJ2566] [尺取法]
阿新 • • 發佈:2018-07-12
none long n) lower NPU using test seq oid
題意
給出一個整數列,求一段子序列之和最接近所給出的t。輸出該段子序列之和及左右端點。
Input
The input file contains several test cases. Each test case starts with two numbers n and k. Input is terminated by n=k=0. Otherwise, 1<=n<=100000 and there follow n integers with absolute values <=10000 which constitute the sequence. Then follow k queries for this sequence. Each query is a target t with 0<=t<=1000000000.Output
For each query output 3 numbers on a line: some closest absolute sum and the lower and upper indices of some range where this absolute sum is achieved. Possible indices start with 1 and go up to n.Sample Input
5 1 -10 -5 0 5 10 3 10 2 -9 8 -7 6 -5 4 -3 2 -1 0 5 11 15 2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 15 100 0 0
Sample Output
5 4 4
5 2 8
9 1 1
15 1 15
15 1 15
分析
這道題可以看得出來是要用尺取法,尺取法的關鍵是要找到單調性。而序列時正時負,顯然是不滿足單調性的。
如果記錄下前綴和,並排好序,這樣就滿足單調性了,就可以使用前綴和了
代碼
1 #include<set> 2 #include<map> 3 #include<queue> 4 #include<stack> 5 #include<cmath> 6 #include<cstdio> 7View Code#include<cstring> 8 #include<iostream> 9 #include<algorithm> 10 #define RG register int 11 #define rep(i,a,b) for(RG i=a;i<=b;++i) 12 #define per(i,a,b) for(RG i=a;i>=b;--i) 13 #define ll long long 14 #define inf (1<<30) 15 #define maxn 100005 16 using namespace std; 17 int n,k; 18 int num[maxn]; 19 struct P{ 20 int id,s; 21 inline int operator < (const P &a)const{ 22 return s==a.s?id<a.id:s<a.s; 23 } 24 }p[maxn]; 25 inline int read() 26 { 27 int x=0,f=1;char c=getchar(); 28 while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} 29 while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} 30 return x*f; 31 } 32 33 void solve() 34 { 35 int aim=read(); 36 int l=0,r=1,mn=inf,al,ar,ans; 37 while(l<=n&&r<=n&&mn) 38 { 39 int cal=p[r].s-p[l].s; 40 if(abs(cal-aim)<mn) 41 { 42 mn=abs(cal-aim); 43 al=p[r].id,ar=p[l].id,ans=cal; 44 } 45 if(cal>aim) ++l; 46 else if(cal<aim) ++r; 47 else break; 48 if(l==r) ++r; 49 } 50 if(al>ar) swap(al,ar); 51 printf("%d %d %d\n",ans,al+1,ar); 52 } 53 54 int main() 55 { 56 while(1) 57 { 58 n=read(),k=read(); 59 if(!n&&!k) return 0; 60 rep(i,1,n) num[i]=read(); 61 p[0]=(P){0,0}; 62 rep(i,1,n) p[i].s=p[i-1].s+num[i],p[i].id=i; 63 sort(p,p+1+n); 64 rep(i,1,k) solve(); 65 } 66 return 0; 67 }
Bound Found [POJ2566] [尺取法]