Cod sursa(job #466638)

Utilizator cosmin79Carabet Cosmin Andrei cosmin79 Data 27 iunie 2010 12:29:29
Problema Numarare Scor 30
Compilator c Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 1 Marime 1.31 kb
#include <stdio.h>
#define NMAX 100005
#define ll long long
int n,A[NMAX];
ll rez,S[NMAX];
void read()
{
    scanf("%d",&n);
    int i;
    for (i=1; i<=n; i++)
    {
        scanf("%d",&A[i]);
        S[i]=S[i-1]+A[i];
    }
}
void solve()
{
   int i,s,st,dr;
   for (i=1; i<n; i++)
   {
       st=i; dr=i+1;
       s=A[st]+A[dr];
       while (st>1 && dr<n)
           if (A[st-1]+A[dr+1]==s)
                st--,dr++;
           else
                break ;
       rez+=i-st+1;
   }
}
inline int ok(int st,int dr,int suma)
{
    if (A[st]+A[dr]!=suma)
        return 0;
    int per=(dr-st+1)/2;
    ll total=(ll)per*suma;
    if (S[dr]-S[st-1]!=total)
        return 0;
    return 1;
}
int cbin(int suma,int poz)
{
    int i,step=(1<<17);
    for (i=poz; step; step>>=1)
        if (i-step>0 && 2*poz+1-i+step<=n && ok(i-step,2*poz+1-i+step,suma))
            i-=step;
    return i;
}
void solve2()
{
    int i,poz;
    for (i=1; i<n; i++)
    {
        poz=cbin(A[i]+A[i+1],i);
        rez+=i-poz+1;
    }
}
int main()
{
    freopen("numarare.in","r",stdin);
    freopen("numarare.out","w",stdout);
    read();
    if (n<=3000)
    {
        solve();
        printf("%lld\n",rez);
        return 0;
    }
    solve2();
    printf("%lld\n",rez);
    return 0;
}