Cod sursa(job #244365)

Utilizator mika17Mihai Alex Ionescu mika17 Data 14 ianuarie 2009 22:16:08
Problema Oite Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.27 kb
#include <cstdio>
#include <vector>
#include <queue>
#define fi first
#define se second
using namespace std;

const int NMAX = 1024, HSIZE = 39107;
const double knt = 0.61803398;
int N,S,c[NMAX];
vector< pair<int,int> > hash[HSIZE];
queue < int > Q;
bool inq[HSIZE];

inline int h(int x) {

        return int( (double(x * knt) - int(x * knt)) * (HSIZE-1) );
}

int search(int x,int ind)
{
        int hh = h(x);

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

        return -1;
}

void insert(int x,int ind) {

        int hh = h(x), t = search(x,ind);
        if(t == -1)
          hash[hh].push_back(make_pair(x,1));
         else hash[hh][t] . se ++;

        if(!inq[hh]) Q.push(hh), inq[hh] = 1;
}

int count(int x,int ind) {

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

        for(i = hash[pos].size() - 1; i >= 0; --i)
        {
         if(hash[pos][i] . fi == x) cnt += hash[pos][i] . se;
          else
           if(hash[pos][i] . fi < 0 && hash[pos][i] . fi > -ind) break;
        }

        return cnt;
}

/* explicatie  hash-ul retine si primul indice i al sumelor (i,j)
cu valoare negativa ( -i) si daca gasim elemente egale cu x
cu indicele negativ mai mare (adica cu indicele pozitiv mai mic)
decat i cnt devine 0
*/


void debug()
{
 for(int i=0;i < HSIZE; ++i)
 {
  for(int j=0; j < (int)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]);

        for(int i=1;i<N;++i)
        {
         for(int j=i+1;j<=N;++j)
          insert(c[i]+c[j],i);

         while(!Q.empty())
         {
          hash[Q.front()].push_back(make_pair(-i,-i));
          inq[Q.front()] = 0;
          Q.pop();
         }
        }
        //debug();
        int cnt = 0;
        for(int i=1;i<N;++i)
         for(int j=i+1;j<=N;++j)
          cnt += count(S - c[i] - c[j],j+1);

        printf("%d",cnt);

        return 0;
}