51Nod 1094 和为k 的连续区间 题解

来源:互联网 发布:婚礼发布网站源码java 编辑:程序博客网 时间:2024/06/05 15:53

题目链接

51Nod 1094: 和为k 的连续区间

题意

一整数数列a1, a2, an(有正有负),以及另一个整数k,求一个区间[i,j](1ijn), 使得ai++aj=k。其中ai,k[109,109], N[2,104]

题解

我想说这题数据出得太水了,网上那些O(n2) 的做法都能过,还有用map 优化的,降到O(nlogn)也有点玄学,我觉得应该把N 取到[2,105] 的,其实比较稳的O(nlogn) 的解法还是很好想的。
用一个结构体存两个int,一个表示前缀和,一个表示当前所在位置,以前缀和为主关键字从小到大排序,然后放到set 里面find 就行了。

过题代码

#include <set>#include <cstdio>using namespace std;#define LL long longconst int maxn = 10005;struct Node {    LL sum;    int pos;    Node(LL s, int p) {        sum = s;        pos = p;    }};bool operator<(const Node &a, const Node &b) {    if(a.sum == b.sum) return a.pos < b.pos;    return a.sum < b.sum;}bool flag;LL n, k;LL num[maxn], sum[maxn];set<Node> s;set<Node>::iterator it;int main() {    scanf("%lld%lld", &n, &k);    for(int i = 0; i < n; ++i) {        scanf("%lld", &num[i]);        sum[i + 1] = sum[i] + num[i];        s.insert(Node(sum[i + 1], i + 1));    }    for(int i = 0; i < n; ++i) {        it = s.lower_bound(Node(sum[i] + k, i + 1));        if(it->sum == sum[i] + k) {            flag = true;            printf("%d %d\n", i + 1, it->pos);            break;        }    }    if(!flag) {        printf("No Solution\n");    }    return 0;}