Cod sursa(job #52511)

Utilizator raula_sanChis Raoul raula_san Data 19 aprilie 2007 09:26:32
Problema Oite Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <stdio.h>

int N, M, step;

#define dim 1025
long L, ret;
long A[dim];

struct elem
{      long v;
       int i, j;
} S[dim*dim]; 

void get_data();
void solve();
void print();

void sort();
void up(int);
void swap(int, int);
void restore(int, int);

int b_search(int);

int main()
{
    get_data();
    sort();
    solve();
    print();
    
    return 0;
}

void get_data()
{
     freopen("oite.in", "r", stdin);
     
     long i, j;
     for(scanf("%d %ld", &N, &L), i=1; i<=N; ++i)
              scanf("%ld", A+i);
              
     for(i=1; i<N; ++i)
              for(j=i+1; j<=N; ++j)
              {
                         S[++M].v = A[i] + A[j];
                         S[M].i = i;
                         S[M].j = j;
              }
     for(step=1; step<=M; step<<=1);
     
     fclose(stdout);
}

void sort()
{
     int i;
     for(i=2; i<=M; ++i) up(i);
     for(i=M; i>1;)
     {
              swap(1, i);
              -- i;
              restore(1, i);
     }
}

void up(int k)
{
     if(k <= 1) return;
     int t = k >> 1;
     
	 if(S[t].v < S[k].v)
     {
             swap(t, k);
             up(t);
     }
}

void swap(int i, int j)
{
	 elem t = S[i];
	 S[i] = S[j];
	 S[j] = t;
}

void restore(int r, int b)
{
     if(r<<1 <= b)
     {
             int st, dr, x;
			 st = S[r<<1].v;

			 if((r<<1)+1 <= b) dr = S[(r<<1)+1].v;
             else dr = st-1;
             
             if(st > dr) x = r<<1;
             else x = (r<<1) + 1;
             
			 if(S[r].v < S[x].v)
             {
                     swap(r, x);
                     restore(x, b);
             }
     }
}

void solve()
{
     int i, j, p;
     for(i=1; i<=M; ++i)
	 {
			  p = 0;
			  p = b_search(L-S[i].v);

			  for(j=p; j; --j)
				if(S[j].v != L-S[i].v) break;
					else
					{
						if(S[i].i != S[j].i && S[i].i != S[j].j
						&& S[i].j != S[j].i && S[i].j != S[j].j)
							++ ret;
					}
	 }
}

int b_search(int value)
{
	int i, x=step;
	for(i=1; x; x>>=1)
			 if(i+x <= M && S[i+x].v <= value)
					   i += x;
    return i;
}

void print()
{
     freopen("oite.out", "w", stdout);
     
	 printf("%ld", ret/6);
     
     fclose(stdout);
}