poj2566Bound Found(前缀和+尺取法)

http://poj.org/problem?id=2566

开始看到这道题时不会做,看了题解才会的,由于原序列散乱,不知道怎么加才能最大,而尺取法要在序列有序才能进行,所以可以用前缀和来使序列单调。定义pair<ilong,long> ss前面记录千缀合,后面记录编号,然后根据千缀合进行大小排序,sort默认按ss.first从大到小排序的,所以有了单调性

所以,ss[j].first-ss[i].first就是从ss[i].second到ss[j].second的和,令l=0,r=1

若ss[r].first-ss[l].first大于t,则l++,小于t则r++,等于t时,ss[l].second,ss[r].second就是左右端点

如果l==r时r++,序列不能为空

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<cmath>
#define INF 0x3f3f3f3f
#define ll long long
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define DEBUG cout<<endl<<"DEBUG"<<endl;
using namespace std;
typedef pair<ll, ll> p;
ll n, k, arr[100010], t;
p ss[100010];
ll abss(ll x) {
    return x < 0 ? -x : x;
}
int main() {
    while(cin >> n >> k && (n + k)) {
        ss[0] = p(0, 0);
        for(int i = 1; i <= n; i++)
            cin >> arr[i], ss[i] = p(ss[i - 1].first + arr[i], i);
        sort(ss, ss + n + 1);
        for(int i = 1; i <= k; i++) {
            cin >> t;
            ll l = 0, r = 1, x, y, s, cha = INF;
            while(r <= n) {
                ll b = ss[r].first - ss[l].first;
                if(abss(t - b) < cha) {
                    cha = abss(t - b);
                    s = b;
                    x = ss[l].second;
                    y = ss[r].second;
                }
                if(b > t)
                    l++;
                else if(b < t)
                    r++;
                else
                    break;
                if(l == r)
                    r++;
            }
            if(y < x)
                swap(y, x);
            cout << s << " " << x + 1 << " " << y << endl;
        }
    }
    return 0;
}

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值