Advertisement
Guest User

Auction solution (probably)

a guest
Jan 24th, 2012
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.04 KB | None | 0 0
  1. # include <algorithm>
  2. # include <iostream>
  3. # include <cstring>
  4. # include <vector>
  5. # include <cstdio>
  6. # include <queue>
  7. # define long long long // :-)
  8. using namespace std;
  9. long const lots=10000000;
  10. template<class Pred> struct rmq;
  11.  
  12. /*.. snip "lrmq.hh" ..*/
  13. /*.. snip "rsort.hh" ..*/
  14.  
  15. typedef pair<long,long> pill;
  16. struct trill{
  17.   long a,b,c;
  18.   trill(long x=0,long y=0,long z=0):a(x),b(y),c(z){}
  19.   bool operator<(trill const o)const{
  20.     return a<o.a or a==o.a and (b<o.b or b==o.b and c<o.c);
  21.   }
  22. };
  23.  
  24. typedef vector<pill> vpill;
  25. typedef vector<trill> vtrill;
  26. rmq<less   <long>>** lo_q;
  27. rmq<greater<long>>** hi_q;
  28. long* orbit[3];
  29. long* space;
  30. long* assoc;
  31. long *pvp,*wvp;
  32. long pc,wc;
  33.  
  34. int main(){
  35.   pvp=new long[lots*3+4];
  36.   wvp=new long[lots*3+4];
  37.  
  38.   for (int i=3; i--;) orbit[i]=new long[lots+200];
  39.   space=new long[lots+200];
  40.   assoc=new long[lots*2+200];
  41.  
  42.   lo_q=new rmq<less   <long>> * [lots];
  43.   hi_q=new rmq<greater<long>> * [lots];
  44.  
  45.   int testcase=1;
  46.   int tsts; scanf("%d",&tsts); while (tsts--){
  47.     long* pv=pvp+lots; // price value
  48.     long* wv=wvp+lots; // weight value
  49.  
  50.     /* number of elements,
  51.        first price,
  52.        first weight,
  53.        price mod,
  54.        weight mod,
  55.        price multiple,
  56.        price add,
  57.        weight multiple,
  58.        weight add */
  59.     long n, p1,w1, pod,wod, pm,pa, wm,wa;
  60.     cin>>n>>p1>>w1>>pod>>wod>>pm>>pa>>wm>>wa;
  61.     vector<trill> dn,up;
  62.  
  63.     // generate the sequence cycles
  64.     pv[0]=p1; wv[0]=w1;
  65.     pc=0,wc=0;
  66.     {
  67.       // might need up to n*2 elements at first (>M+1 and >K+1 never happen)
  68.       int* lap=new int[pod+1]; for (long i=pod+1; i--;) lap[i]=0; lap[p1]=1;
  69.       int* law=new int[wod+1]; for (long i=wod+1; i--;) law[i]=0; law[w1]=1;
  70.       while (++pc<n*2) {pv[pc]=((pv[pc-1]*pm+pa)%pod)+1; if (lap[pv[pc]]) break; else lap[pv[pc]]=pc+1;}
  71.       while (++wc<n*2) {wv[wc]=((wv[wc-1]*wm+wa)%wod)+1; if (law[wv[wc]]) break; else law[wv[wc]]=wc+1;}
  72.  
  73.       // calculate duplication count
  74.       long pdup=lap[pv[pc]]-1;
  75.       long wdup=law[wv[wc]]-1;
  76.       if (pdup==pc+1) pdup=0; pdup=max(min(pdup,n-1),0ll);
  77.       if (wdup==wc+1) wdup=0; wdup=max(min(wdup,n-1),0ll);
  78.  
  79.       // it's easier to know that length(pv) is not greater than length(wv)
  80.       if (wc-wdup<pc-pdup){
  81.         swap(wc,pc);
  82.         swap(wv,pv);
  83.         swap(pdup,wdup);
  84.       }
  85.  
  86.       // unique elements are a special case
  87.       for (long i=max(pdup,wdup); i--;)
  88.         dn.push_back(trill(wv[i%wc],pv[i%pc],1)),
  89.         up.push_back(trill(wv[i%wc],pv[i%pc],1)),
  90.         --n;
  91.  
  92.       pv+=pdup, pc-=pdup;
  93.       wv+=wdup, wc-=wdup;
  94.  
  95.       pc=min((long)pc,n);
  96.       wc=min((long)wc,n);
  97.       while (wdup>pdup and wdup--){
  98.         ++pv, pv[pc-1]=pv[-1];
  99.       }
  100.       while (pdup>wdup and pdup--){
  101.         ++wv, wv[wc-1]=wv[-1];
  102.       }
  103.  
  104.       delete[] lap; delete[] law;
  105.     }
  106.  
  107.     // the drift per generation is the reference list length mod the basis list length
  108.     long drift=wc%pc;
  109.  
  110.     // build orbits
  111.     int orbits=0, spaces=0;
  112.     {
  113.       bool* done=new bool[pc];
  114.       for (int i=pc; i--;) done[i]=false;
  115.       for (int i=0; i<pc; i++)
  116.         if (not done[i]){
  117.           orbit[2][orbits  ]=i;
  118.           orbit[0][orbits  ]=spaces;
  119.           for (int j=i; !done[j]; j=fastmod(j+drift,pc))
  120.             done[j]=true, space[spaces]=pv[j], assoc[j*2]=orbits, assoc[j*2+1]=spaces++;
  121.           orbit[1][orbits++]=spaces;
  122.         }
  123.       delete[] done;
  124.     }
  125.  
  126.     // construct range minimum query tables
  127.     for (int i=orbits; i--;)
  128.       lo_q[i]=new rmq<   less<long>>(space+orbit[0][i],space+orbit[1][i]),
  129.       hi_q[i]=new rmq<greater<long>>(space+orbit[0][i],space+orbit[1][i]);
  130.  
  131.     // find and count outliers
  132.     for (long i=0; i<wc; i++){
  133.       long id=i%pc;
  134.       long count=(n-i+wc-1)/wc;
  135.       ulong off=orbit[0][assoc[id*2]];
  136.       long l=assoc[id*2+1]-off;
  137.       long r=l+count;
  138.  
  139.       long period=(orbit[1][assoc[id*2]]-orbit[0][assoc[id*2]])*wc;
  140.       long loop=orbit[1][assoc[id*2]]-orbit[0][assoc[id*2]];
  141.  
  142.       long u=lo_q[assoc[id*2]]->query(l,r); dn.push_back(trill(wv[i],space[u+off],(count-((loop+u-l)%loop)+loop-1)/loop));
  143.       long v=hi_q[assoc[id*2]]->query(l,r); up.push_back(trill(wv[i],space[v+off],(count-((loop+v-l)%loop)+loop-1)/loop));
  144.     }
  145.  
  146.     for (int i=orbits; i--;)
  147.       delete lo_q[i], delete hi_[i];
  148.  
  149.     rad_sort(dn.begin(),dn.end());
  150.     rad_sort(up.begin(),up.end());
  151.  
  152.     long red=0,rep=0;
  153.     long sad=(1ll<<40ll),sap=-(1ll<<40ll);
  154.     for (long i=0; i<dn.size(); i++){
  155.        //if (dn[i].b<sad) printf("%lld: %lld * %lld\n",dn[i].a,dn[i].b,dn[i].c);
  156.       if (dn[i].b<sad)
  157.         sad=dn[i].b,
  158.         red+=dn[i].c;
  159.     }
  160.     for (long i=up.size(); i--;){
  161.       //if (up[i].b>sap) printf("%lld: %lld * %lld\n",up[i].a,up[i].b,up[i].c);
  162.       if (up[i].b>sap)
  163.         sap=up[i].b,
  164.         rep+=up[i].c;
  165.     }
  166.  
  167.     printf("Case #%d: %lld %lld\n",testcase++,rep,red);
  168.   }
  169.  
  170.   for (long i=3; i--;) delete[] orbit[i];
  171.   delete[] space;
  172.   delete[] assoc;
  173.   delete[] pvp;
  174.   delete[] wvp;
  175.   delete[] lo_q;
  176.   delete[] hi_q;
  177. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement