Google code jam Round1B Problem B

来源:互联网 发布:计算机编程专业 编辑:程序博客网 时间:2024/05/17 08:55
 #include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <assert.h>
#include <boost/pending/disjoint_sets.hpp>
using namespace std;
using namespace boost;
    typedef
      disjoint_sets_with_storage<identity_property_map, identity_property_map,
      find_with_full_path_compression> ds_type;
long long isPrime(long long n)
{
  long long i = 2;

  for (; i * i <= n; i = (i + 1) | 1)
    if (n % i == 0)
      return 0;
  return n > 1;
}
void primeSet(int p, int n, vector < long long >&primeSet, map < int, int >&val_pos)
{
  int i;
  int pos = 0;

  for (i = p; i <= n; i++) {
    if (isPrime(i)) {
      primeSet.push_back(i);
      val_pos[i] = pos++;
    }
  }
}

inline void union_set(int *& arr, int*& rank, int a, int b)
{
  //assert(arr[a] == -1 && arr[b] == -1 && a != b);
  if(rank[a] > rank[b])
      arr[b] = a;
  else
      arr[a] = b;
  if(rank[a] == rank[b])
    rank[b]++;
  //return a;
}
int union_find(int *& arr, int pos)
{
  if(arr[pos] != pos) {
    arr[pos] = union_find(arr, arr[pos]);
  }
  return arr[pos];
}


struct node
{
    int root;    
    int rank;
};

const int poolSize=240000;
node nodePool[poolSize];
    

void makeSet(int cnt)
{
    nodePool[cnt].root=cnt;
    nodePool[cnt].rank = 0;
}

//  recursive findSet
int findSet(int x)    
{
    if(x!=nodePool[x].root)
        nodePool[x].root = findSet(nodePool[x].root);
    
    return nodePool[x].root;
}
int countSet(int size)
{
    int count = 0;
    for(int i = 0; i < size; i++)
        if( nodePool[i].root == i)
            count++;
    return count;
}
void unionSet(int x, int y)
{
    x= findSet(x);
    y= findSet(y);
    if(x==y)  return;  // in the same set
    
    if(nodePool[x].rank > nodePool[x].rank ) {
        nodePool[y].root=x;
    }
    else  {
        nodePool[x].root=y;
        if(nodePool[x].rank==nodePool[y].rank) {
            nodePool[y].rank++;
        }
    }
}




int main(int argc, char **argv)
{
  string line;
  ifstream myfile(argv[1]);
  char outfile[255];

  sprintf(outfile, "%s.out", argv[1]);
  ofstream out(outfile);

  if (myfile.is_open()) {

    getline(myfile, line);
    int cases_count = atoi(line.c_str());

    for (int round_i = 0; round_i < cases_count; round_i++) {
      long long A, B, P;

      myfile >> A >> B >> P;
      getline(myfile, line);

      // compute on customer perfer
      int set_count = 0;
      vector < long long >prm_set;
      map < int, int >val_pos;

      cout << " Processing: P B A " << P << " " << B << " " << A << endl;
      primeSet(P, B - A, prm_set, val_pos);

      int size = prm_set.size();
    
           

      // cout << size << endl;
      // for(int k = 0 ; k < size ; k++)
      // cout << " " << prm_set[k] ; cout << endl;
      //int *sets = (int *)malloc(sizeof(int) * size);

    //for(int i = 0; i < size; i++)
    //    sets[i] = i;
      //memset(sets, 0xFF, sizeof(int) * size);   // set to -1 as parent
      //int *rank = (int *)malloc(sizeof(int) * size);
      //memset(rank, 0, sizeof(int) * size);   // set to -1 as parent */


    //ds_type ds(size);
    for(int i = 0; i < size; i++)
        makeSet(i);


      /* for (long long i = A; i <= B; i++) { int union_before; bool single =
         true; bool need_union = false;
         for(int j = 0; j < size; j++) {
         if(i % prm_set[j] == 0 ){ single = false; break; } } if(single)
         set_count++; } */
      cout << "prime computed" << endl;
      cout << "size:" << size << endl;
      int len = B - A + 1;
      int * status = (int*) malloc(sizeof(int*) * len);
      memset(status, 0, sizeof(int) * len);
      for (int i = 0; i < size; i++) {
      //if( A < prm_set[i])
    //    break;
      long long start;
      if(A % prm_set[i] == 0)
        start = A;
        else
                start = (prm_set[i] - A % prm_set[i]) + A;
      
      for(long long  j = start; j <= B; j = j+prm_set[i]){
        status[j - A] = 1;// 1 means a composite
      }
      }
      for(int i = 0; i < len; i++){
        if(status[i] == 0)
        set_count++;    
    }
cout << "cross finished " << set_count <<  endl;
      for (int i = 0; i < size; i++) {
        //int top1 = i;
    //top1 = union_find(sets, i);
      //int i = 0;
    //if(i < size) {
        // if(sets[i] == -1)
        for (int j = i + 1; j < size; j++) {
          //  int top2 = j;
      //  top2 = union_find(sets, j);
      //  if(top1 == top2)
    //    continue;
          long long pq = prm_set[i] * prm_set[j];
          if (pq > B )
            continue;
          long long left = A % pq;

          if ( left == 0 ||  A - left + pq  < B ) {
              //union_set(sets, rank, top1, top2);
              unionSet(i,j);
      }
        }
      }
     //or (int i = 0; i < size; i++) {
    //cout << sets[i] << " ";
    //cout << rank[i] << " ";
        //if (sets[i] == i)
        //  set_count++;
      //}
    //cout << endl;
      set_count += countSet(size);
      out << "Case #" << round_i + 1 << ": " << set_count << endl;
      cout << "Case #" << round_i + 1 << ": " << set_count << endl;
    }
    myfile.close();
    out.close();
  }
  return 0;
}
原创粉丝点击