Cod sursa(job #244812)

Utilizator mika17Mihai Alex Ionescu mika17 Data 16 ianuarie 2009 00:15:38
Problema Oite Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#define fi first
#define se second
using namespace std;

const int NMAX = 1024, HSIZE = 3033;
const double knt = 0.61803398;
const pair <int,int> DELETED = make_pair(-1,-1);

int N,S,c[NMAX];
typedef vector< pair<int,int> > my_hash[HSIZE];
my_hash hash1, hash2;

int h(int x,int i) {

        if(i==1)
         return int( (double(x * knt) - int(x * knt)) * (HSIZE-1) );
        else
         return x % HSIZE;
}

int search(my_hash hash,int x,int i)
{
        int hh = h(x,i);

        for(int i = hash[hh].size() - 1; i >= 0; --i)
          if(hash[hh][i] . fi == x) return i;

        return -1;
}

void insert(my_hash hash,int x,int i,int t) {

        int hh = h(x,i);

        if(t == -1)
           hash[hh].push_back(make_pair(x,1));

         else hash[hh][t] . se ++;
}

void insert_r(int x)
{
        int t;
        if( (t = search(hash1,x,1)) )
         {insert(hash1,x,1,t); return;}
        if( (t = search(hash2,x,2)) )
         {insert(hash2,x,2,t); return;}

        int hh1 = h(x,1), hh2 = h(x,2);
        
        hash1[hh1].size() < hash2[hh2].size() ?
         insert(hash1,x,1,-1) : insert(hash2,x,2,-1);
}

int erase(my_hash hash,int x,int i) {

        int hh = h(x,i);

        for(unsigned i = 0 ; i < hash[hh].size(); ++i)
         if(hash[hh][i] . fi == x)
         {
          if(hash[hh][i] . se == 1)
            hash[hh][i] = DELETED;

           else hash[hh][i] . se --;
          return 1;
         }
         return 0;
}

void erase_r(int x) {

        if(!erase(hash1,x,1))
         erase(hash2,x,2);
}

int count(my_hash hash,int x,int i) {

        if(x<0) return 0;
        
        int hh = h(x,i);

        for(int i = hash[hh].size() - 1; i >= 0; --i)
        {
         if(hash[hh][i] . fi == x) return hash[hh][i] . se;
        }

        return 0;
}

int count_r(int x) {

        int cnt = count(hash1,x,1);
        if(!cnt)
         cnt = count(hash2,x,2);
        return cnt;
}

void debug(my_hash hash)
{
 for(int i=0;i < HSIZE; ++i)
 {
  for(unsigned j=0; j < hash[i].size(); ++j)
   printf("(%d %d) ",hash[i][j]. fi, hash[i][j] . se);
  printf("\n");
 }
}

int main() {

        freopen("oite.in","r",stdin);
        freopen("oite.out","w",stdout);

        scanf("%d%d",&N,&S);
        for(int i=1;i<=N;++i)
         scanf("%d",&c[i]);

        sort(c,c+N);

        for(int i=3;i<N;++i)
        {
         for(int j=i+1;j<=N;++j)
          insert_r(c[i]+c[j]);
        }

        //debug();

        int cnt = 0;
        for(int j=2;j<=N-2;++j)
        {
         for(int i=1; i<j; ++i)
          cnt += count_r(S - c[i] - c[j]);

         for(int i=j+2;i<=N;++i)
          erase_r(c[j+1] + c[i]);
        }

        printf("%d",cnt);

        return 0;
}