Cod sursa(job #1102741)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 9 februarie 2014 14:38:12
Problema Range minimum query Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.94 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>

#define Nmax 66000
#define INF 999999999999999

using namespace std;

int N,A,B;
long long v[2*Nmax],ans1 = -INF,ans2= INF;
vector<int> divi;

int M[18][2*Nmax],m[18][2*Nmax];

#define DIM 400000
char buff[DIM];
int poz=0;

void citeste(long long &numar)
{
     numar = 0;
     while (buff[poz] < '0' || buff[poz] > '9')
          if (++poz == DIM)
               fread(buff,1,DIM,stdin),poz=0;
     while ('0'<=buff[poz] && buff[poz]<='9')
     {
          numar = numar*10 + buff[poz] - '0';
          if (++poz == DIM)
               fread(buff,1,DIM,stdin),poz=0;
     }
}

long long maxim(long long x,long long y)
{
    if (x > y) return x;
    return y;
}
long long minim(long long x,long long y)
{
    if (x < y) return x;
    return y;
}


void read()
{
    long long ax;
    citeste(ax);
    N = ax;
    for(int i = 1; i <= N; ++i)
    {
        citeste(v[i]);
        v[i+N] = v[i];
        M[0][i] = M[0][i+N] = v[i];
        m[0][i] = m[0][i+N] = v[i];
    }
}

void RMQ()
{
    int x = 1;
    for(int i = 1; i <= 17; ++i)
    {
        for(int j = 1; j<= 2*N; ++j)
            if(j + x > 2*N){
                    m[i][j] = m[i-1][j];
                    M[i][j] = M[i-1][j];
            }
            else{
                    m[i][j] = minim(m[i-1][j],m[i-1][j+x]);
                    M[i][j] = maxim(M[i-1][j],M[i-1][j+x]);
            }
        x<<=1;
    }
}

int querry(int poz,int lenght,int type)
{
    int line = log2(lenght);
    if(type == 1)/// maxim
        return maxim(M[line][poz],M[line][poz+lenght-(1<<line)]);
    else
        return minim(m[line][poz],m[line][poz+lenght-(1<<line)]);
}

long long diff(int x,int y)
{
    long long M = v[x],m = v[x];
    for(int i = x+1; i <= y; ++i)
    {
        if(v[i] > M)
            M = v[i];
        if(v[i] < m)
            m = v[i];
    }
    return M - m;
}


void diviz()
{
    int x = N;
    for(int i = 1; i*i < x; ++i)
        if(x % i == 0)
        {
            divi.push_back(i);
            divi.push_back(x/i);
        }
    for(int i = 1; i * i <= x; ++i)
        if( i * i == x)
            divi.push_back(i);
    sort(divi.begin(),divi.end());
}
long long ans = 0;

void pachete(int L)
{
    long long crt;
    for(int pz = 1; pz <= L; ++ pz)
    {
        crt = 0;
        for(int i = pz; i <= N - L + pz; i += L)
        {
            A = i;
            B = i + L - 1;
            ans1 = querry(A,B-A+1,1);
            ans2 = querry(A,B-A+1,2);
            crt =crt + (long long)(ans1 - ans2);
        }
        if(ans <= crt)
            ans = crt;
    }
}

int main()
{
    freopen("collar.in","r",stdin);
    freopen("collar.out","w",stdout);

    read();
    diviz();
    RMQ();

    for(int d = 0; d < divi.size(); ++d)
        pachete(divi[d]);
    printf("%lld\n",ans);

    return 0;
}