D. Array Division

http://codeforces.com/contest/808/problem/D

一开始是没什么想法的,然后回顾下自己想题的思路,慢慢就想出来了。首先要找到是否有这样的一个位置使得:

前缀和 == 后缀和,可以二分来求。

然后可以这样想,如果对于每一个数字,我都去移动一下,每个位置都试一下,复杂度多少?显然不能承受。

然后优化下这个思路,有了一点思路,优化到极致,看看能不能过,不能过就换思路吧。一般来说,每一个位置都试一下,是很没必要的。一般都是有一个位置是最优的。

这个位置就是放在最前或者放在最后。可以这样去想。

如果原来的数组,是不存在这样的位置的,那么移动a[i]到某一个位置后,存在了这样的位置。那么肯定是把这个数字移动去了前缀和的贡献哪里(后缀和同理),因为不是移动到前缀和哪里,就相当于没移。

所以把它移动到第1位,前缀和就肯定包含它了。

最后还是被hack,细节写歪了

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 1000000 + 20;
int n;
int a[maxn];
LL sum[maxn];
LL nowDel;
LL ask(int pos) {
    if (pos < nowDel) {
        return sum[pos] - a[pos] + a[nowDel];
    } else return sum[pos];
}
LL ask2(int pos) {
    if (pos >= nowDel) {
        return sum[pos] - a[nowDel] + a[pos + 1];
    } else return sum[pos];
}
bool tofind(int which) {
    int be = 2, en = n;
    while (be <= en) {
        int mid = (be + en) >> 1;
        LL lef;
        if (which == 1) lef = ask(mid - 1);
        else lef = ask2(mid - 1);
        LL rig = sum[n] - lef;
        if (lef < rig) be = mid + 1;
        else en = mid - 1;
    }
    LL lef;
    if (which == 1) lef = ask(en);
    else lef = ask2(en);
    return lef * 2 == sum[n];
}
void work() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
        sum[i] = sum[i - 1] + a[i];
    }
//    nowDel = 2;
//    tofind(2);
    for (int i = 1; i <= n; ++i) {
        nowDel = i;
        if (tofind(1)) {
            printf("YES\n");
            return;
        }
        if (tofind(2)) {
            printf("YES\n");
            return;
        }
    }
    printf("NO\n");
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}
View Code

 

posted on 2017-05-17 17:05  stupid_one  阅读(287)  评论(0编辑  收藏  举报

导航