• Bound Found [POJ2566] [尺取法]


    题意

    给出一个整数列,求一段子序列之和最接近所给出的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>
     7 #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
    ",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 }
    View Code
  • 相关阅读:
    poj2452
    bnuoj16491
    1326: The contest(并查集+分组背包)
    BNUOJ-1065或运算的简单解法
    递推、规律思维题总结
    uva10160(dfs+状态压缩)
    第七章 人工智能,7.1 基于深度强化学习与自适应在线学习的搜索和推荐算法研究(作者:灵培、霹雳、哲予)
    第六章 大数据,6.3 突破传统,4k大屏的沉浸式体验(作者: 彦川、小丛)
    第六章 大数据,6.2 双11背后的大规模数据处理(作者:惠岸 朋春 谦乐)
    第六章 大数据,6.1 双11数据大屏背后的实时计算处理(作者:藏六 黄晓锋 同杰)
  • 原文地址:https://www.cnblogs.com/ibilllee/p/9300321.html
Copyright © 2020-2023  润新知