Cod sursa(job #68904)

Utilizator moga_florianFlorian MOGA moga_florian Data 29 iunie 2007 20:28:43
Problema P-sir Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.51 kb
#include<stdio.h>
#define Nmax 2007

int N,A[Nmax];
unsigned int C[Nmax][Nmax];
int poz[Nmax];
unsigned int sum[Nmax];

void sort(int p)
{
int i,j,k;
     
for(i=1;i<p;i++)
   {
   poz[i]= A[i];
   sum[i]=C[i][p];
   
   j=i;
   while(j/2 && poz[j/2] < poz[j])
       {
       poz[j/2]^=poz[j];
       poz[j]^=poz[j/2];
       poz[j/2]^=poz[j];
       
       sum[j/2]^=sum[j];
       sum[j]^=sum[j/2];
       sum[j/2]^=sum[j];
       
       j/=2;      
       }   
   }
   
i=p-1;
while(i>1)
 {
 poz[1]^=poz[i];
 poz[i]^=poz[1];
 poz[1]^=poz[i];
 
 sum[1]^=sum[i];
 sum[i]^=sum[1];
 sum[1]^=sum[i];
 
 i--;
 
 j=1;
 while(1)
   {
   k=j<<1;
   if(k>i) break;
   if(k+1<=i && poz[k] < poz[k+1]) k++;
   if(poz[j] >= poz[k]) break;
   
   poz[j]^=poz[k];
   poz[k]^=poz[j];
   poz[j]^=poz[k];
   
   sum[j]^=sum[k];
   sum[k]^=sum[j];
   sum[j]^=sum[k];
   
   j=k;         
   }          
 }
 
for(i=1;i<p;i++)
   sum[i]+= sum[i-1];
}

int main()
{
FILE *fin=fopen("psir.in","r"),
     *fout=fopen("psir.out","w");

int i,j,li,lf,mij;
unsigned int total=0;

fscanf(fin,"%d",&N);
for(i=1;i<=N;i++)
   fscanf(fin,"%d",&A[i]);
   
for(i=1;i<N;i++)
  for(j=i+1;j<=N;j++)
     {
     C[i][j]=1;
     total++;
     }
     
for(i=2;i<N;i++)
  {
  //ordine: k i j
  sort(i);
                
  for(j=i+1;j<=N;j++)
    if( A[j] < A[i])
     {              
     //caut A[k] < A[j]
     li=1;
     lf=i-1;
     
     while(lf-li>1)
       {
       mij= (li+lf)>>1;
       if( poz[mij] < A[j])
          li=mij;
       else
          lf=mij;            
       }
       
     if(poz[lf] < A[j])
        {
        C[i][j]=sum[lf];
        total+=C[i][j];       
        }
     else       
     if(poz[li] < A[j])
        {
        C[i][j]= sum[li];
        total+=C[i][j];
        }             
     }
    else
    if(A[j] > A[i])
      {
      //caut A[k] > A[j]
      li=1;
      lf=i-1;
      
      while(lf-li>1)
        {
        mij=(li+lf)>>1;
        if( poz[mij] > A[j])
           lf=mij;
        else
           li=mij;            
        }
        
      if(poz[li]>A[j])
         {
         C[i][j]= sum[i-1] - sum[li-1];
         total+= C[i][j];             
         }
      else        
      if(poz[lf]>A[j])
         {
         C[i][j]= sum[i-1] - sum[lf-1];      
         total+= C[i][j];
         }
      }            
  } 
  
fprintf(fout,"%u\n",total);
      
fclose(fin);
fclose(fout);
return 0;
}