Codeforces 808D Array Division 题解

来源:互联网 发布:淘宝箱小型印刷机 编辑:程序博客网 时间:2024/05/29 04:29

题意

给你一个序列,可以选择一个数移到另一个位置,问是否可以满足将序列分成两个非空连续部分后,两部分数之和相等

思路

先统计所有数之和,如果为奇数,显然不行,然后再从左到右求前缀和,如果前缀和正好是总和一半,那显然可以,如果超过了,就需要前部移一个给后部或者后部移一个给前部,先考虑前部移一个给后部,记下第一个超过的位置t,此时要想满足条件就需要从头到t中减掉一个,然后再加上从t+1开始一个连续区间的数字和满足条件,于是我们先把从t+1开始的连续区间的数字和放进一个set,再从头到t枚举减掉哪一个,看剩下需要的是否在set里,如果有就可以了,再考虑后部移一个给前部,其实是一样的方法,只是所有操作都变成了从右往左而已,如果都不行那就是不行了

代码

#include <cstdio>#include <set>using namespace std;long long a[100001];set<long long> s;int main(){    long long n,add,f,sum,t,add2;    scanf("%I64d",&n);    sum=0;    for(long long i=0;i<n;i++)    {        scanf("%I64d",&a[i]);        sum+=a[i];    }    add=0;    f=0;    if(sum%2==1)        printf("NO\n");    else    {        for(long long i=0;i<n;i++)        {            add+=a[i];            if(2*add==sum)            {                f=1;                break;            }            else if(2*add>sum)            {                t=i;                break;            }        }        if(f==1)            printf("YES\n");        else        {            add2=0;            s.insert(add2);            for(long long i=t+1;i<n;i++)            {                add2+=a[i];                s.insert(add2);            }            for(long long i=0;i<=t;i++)            {                if(s.count(sum/2-add+a[i]))                {                    f=1;                    break;                }            }            if(f==1)                printf("YES\n");            else            {                add2=0;                s.clear();                s.insert(add2);                for(long long i=t-1;i>=0;i--)                {                    add2+=a[i];                    s.insert(add2);                }                for(long long i=n;i>=t;i--)                {                    if(s.count(sum/2-(sum-add+a[t])+a[i]))                    {                        f=1;                        break;                    }                }                if(f==1)                    printf("YES\n");                else printf("NO\n");            }        }    }    return 0;}