CSU

来源:互联网 发布:python range转换list 编辑:程序博客网 时间:2024/05/20 05:07

题目链接


题意:

让你选取三个位置,使得数列分成四部分,每部分的和都相等,问你能否成功.(ai>=0&&ai<=1e9,)


思路:

这个题的话,由于前缀和都是递增的,所以的话我们可以开一个双指针,一个从前往后,一个从后往前,找到和相等的时候,就将中间剩下的部分二分,找到这个中间位置看是否满足,同时维护字典序最小.


#include<bits/stdc++.h>using namespace std;const int maxn=1e5+10;typedef long long ll;int n;ll a[maxn];ll s[maxn];int main(){    while(scanf("%d",&n)!=EOF)    {        memset(s,0,sizeof(s));        for(int i=1;i<=n;i++)        {            scanf("%lld",&a[i]);            s[i]=s[i-1]+a[i];        }        int p1=1,p2=0,p3=n;        int c1=-1,c2=-1,c3=-1;        while(p1+1<=p3+1-4)        {            while(p1<=p3-6&&s[p1]!=s[n]-s[p3-1])            {                while(p1<=p3-6&&s[p1]<s[n]-s[p3-1]) p1++;                while(p1<=p3-6&&s[p1]>s[n]-s[p3-1]) p3--;            }            if(p1>p3-6)                break;            p2=lower_bound(s+p1+2,s+p3-1,s[p1]+s[p1+1])-s;            if(s[p1]==s[p3-2]-s[p2+1]&&p3-p2>=4)            {                if(c1==-1)                {                    c1=p1,c2=p2,c3=p3;                   continue;                }                if(c1<p1)                    break;                if(c2>p2||(c2==p2&&c3>p3))                {                    c2=p2;                    c3=p3;                }            }            p3--;        }        if(c1==-1)            printf("-1\n");        else        printf("%d %d %d\n",c1+1,c2+1,c3-1);    }    return 0;}