Cod sursa(job #1102370)

Utilizator robert.onesimRobert Onesim robert.onesim Data 9 februarie 2014 13:50:38
Problema Range minimum query Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.85 kb
#include <stdio.h>
#include <vector>
#include <math.h>
using namespace std;
#define NMAX 65600
#define LMAX 18

long long int rmq[LMAX][NMAX];
long long int rmq1[LMAX][NMAX];
long long int lg[NMAX];
long long int lg1[NMAX];
long long int a[NMAX];
int n,l,l1,i;
long long int solutie;
void calculeaza(int k)
{
     long int x,y,diff,sh,diff1,sh1,ii,j,sum;
    for(ii=1;ii<=k;ii++)
    {
        x=ii; y=ii+k-1;
        sum=0;
        for(j=1;j<=n/i;j++)
        {
            //min
             diff=y-x+1;
             l=lg[diff];
             sh=diff - (1<<l);
             //max
             diff1=y-x+1;
             l1=lg1[diff];
             sh1=diff1 - (1<<l1);

             sum+=max(rmq1[l1][x],rmq1[l1][x+sh1])-min(rmq[l][x],rmq[l][x+sh]);
              x=x+k;
              y=y+k;
              if(y>n) y=ii-1;
        }
        if (sum>solutie) solutie=sum;
    }


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

    long int j;

    scanf("%ld",&n);

    for (i=1;i<=n;i++)
        scanf("%ld ",&a[i]);
    //range minimum query
    lg[1]=0;
    for (i=2;i<=n;i++)
        lg[i]=lg[i/2]+1;

    for (i=1;i<=n;i++)
        rmq[0][i]=a[i];

    for (i=1; (1 << i) <=n;i++)
        for (j=1;j <= n - (1 << i)+1;j++)
        {
        l=1<<(i-1);
        rmq[i][j]= min( rmq[i-1][j] , rmq[i-1][j+l] );
        }
    //range maximum querry
    lg1[1]=0;
    for (i=2;i<=n;i++)
        lg1[i]=lg1[i/2]+1;

    for (i=1;i<=n;i++)
        rmq1[0][i]=a[i];

    for (i=1; (1 << i) <=n;i++)
        for (j=1;j <= n - (1 << i)+1;j++)
        {
        l=1<<(i-1);
        rmq1[i][j]= max( rmq1[i-1][j] , rmq1[i-1][j+l] );
        }
    solutie=0;
    for(i=2;i<=sqrt(n);i++)
        if(n%i==0)
            calculeaza(i);
    printf("%d",solutie);
    return 0;
}