線段樹學習(2)POI Promotion

今天嘗試寫了一個線段樹的題,POI2000 Promotion,(參考了李睿的論文)一開始建了一個[1,1000000]的線段樹,結果超內存了~後來hash了一下,優化了一下結構,但是wrong answer了,最後把所有的int改爲了__int64,終於AC了
------------------------------------------題目--------------------------------------------------------------------------------
Description Great Bytelandish net of supermarkets asked you for writing a program simulating costs of the promotion being prepared. The promotion has to obey the following rules: 1.A customer, who wants to participate in the promotion, writes on the bill, paid by himself, his personal details and throws it to a special ballot box. 2.At the end of every day of the promotion, two bills are taken out from the ballot box: *** the first bill amounting to the greatest sum is chosen, *** then the bill amounting to the least sum is chosen; The customer, who has paid the greatest bill, gets a money prize equal to the difference between the sum on his bill and the sum on the bill amounting to the least sum. 3.To avoid multiple prizes for one purchase, both bills selected accordingly to the above rules, do not return to the ballot box, but all remaining bills still participate in promotion. Turnovers of the supermarket are very big, thus an assumption can be made, that at the end of every day, before taking out bills amounting to the greatest and the least sum, there are at least 2 bills in the ballot box. Your task is to compute on the basis of information about prices on bills thrown to the ballot box on each day of promotion, what will be the total cost of prizes during the whole promotion. Task Write a program, which: 1.reads a list of prices on bills thrown to the ballot box on each day of the promotion, 2.computes the total cost of prizes paid in consecutive days of promotion, 3.writes the result. Input The first line contains one positive integer n, where 1 <= n <= 5000, which is the duration of promotion in days. Each of the next n lines consists of a sequence of non-negative integers separated by single spaces. Numbers in the (i+1)-th line of the file represent prices on bills thrown to the ballot box on the i-th day of promotion. The first integer in the line is k, 0 <= k <= 10^5, the number of bills from the day, and the next k numbers are positive integers standing for the prices on bills; none of these numbers is greater than 10^6. The total number of bills thrown to the ballot box during the whole promotion does not exceed 10^6. Output The out should contain exactly one integer, which is equal to the total cost of prizes paid during the whole promotion. Sample Input 5 3 1 2 3 2 1 1 4 10 5 5 1 0 1 2 Sample Output 19
----------------------------------------------------------------------------代碼-----------------------------------------------------------------------------------
  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. const __int64 MAXN = 10000;
  5. struct NODE
  6. {
  7.     __int64 l,r,cnt;
  8.     NODE *left_child,*right_child;
  9. };
  10. vector<__int64> hash[10001];
  11. void build (  NODE *v , __int64 l , __int64 r )
  12. {
  13.     NODE *p;
  14.     __int64 m;
  15.     if ( l>=r )
  16.         return ;
  17.     m=(l+r)>>1;
  18.     p=new NODE;
  19.     p->l=l,p->r=m,p->cnt=0,p->left_child=p->right_child=NULL;
  20.     v->left_child=p;
  21.     build(p,l,m);
  22.     p=new NODE;
  23.     p->l=m+1,p->r=r,p->cnt=0,p->left_child=p->right_child=NULL;
  24.     v->right_child=p;
  25.     build(p,m+1,r);
  26. }
  27. void ins ( __int64 d , NODE *v )
  28. {
  29.     __int64 m;
  30.     if ( v==NULL )
  31.         return;
  32.     if ( v->l<=d && d<=v->r )
  33.     {
  34.         v->cnt++;
  35.         m=(v->l+v->r)/2;
  36.         if ( d<=m )
  37.             ins(d,v->left_child);
  38.         else
  39.             ins(d,v->right_child);
  40.     }
  41. }
  42. void del ( __int64 d , NODE *v )
  43. {
  44.     __int64 m;
  45.     if ( v==NULL )
  46.         return;
  47.     if ( v->l<=d && d<=v->r )
  48.     {
  49.         if ( v->cnt>0 )
  50.             v->cnt--;
  51.         m=(v->l+v->r)/2;
  52.         if ( d<=m )
  53.             del(d,v->left_child);
  54.         else
  55.             del(d,v->right_child);
  56.     }
  57. }
  58. __int64 max ( NODE *v  )
  59. {
  60.     if ( v->left_child==NULL ||v->right_child==NULL )
  61.         return v->r;
  62.     if ( v->right_child->cnt )
  63.         return max(v->right_child);
  64.     else
  65.         return max(v->left_child);
  66. }
  67. __int64 min ( NODE *v  )
  68. {
  69.     if ( v->left_child==NULL ||v->right_child==NULL )
  70.         return v->l;
  71.     if ( v->left_child->cnt )
  72.         return min(v->left_child);
  73.     else
  74.         return min(v->right_child);
  75. }
  76. __int64 hash_max ( __int64 f )
  77. {
  78.     vector<__int64>::iterator p,q;
  79.     __int64 res;
  80.     for ( p=q=hash[f].begin() ; p!=hash[f].end() ; p++ )
  81.         if( *q<*p )
  82.             q=p;
  83.     res=*q;
  84.     hash[f].erase(q);
  85.     return res;
  86. }
  87. __int64 hash_min ( __int64 f )
  88. {
  89.     vector<__int64>::iterator p,q;
  90.     __int64 res;
  91.     for ( p=q=hash[f].begin() ; p!=hash[f].end() ; p++ )
  92.         if( *q>*p )
  93.             q=p;
  94.     res=*q;
  95.     hash[f].erase(q);
  96.     return res;
  97. }
  98. int main ( )
  99. {
  100.     NODE *head;
  101.     __int64 c,k,i,j,d,maxnum,minnum,res=0;
  102.     head=new NODE;
  103.     head->cnt=0,head->l=0,head->r=MAXN,head->left_child = head->right_child = NULL;
  104.     build(head,0,MAXN);
  105.     scanf("%I64d",&c);
  106.     for ( i=0 ; i<c ; i++ )
  107.     {
  108.         scanf("%I64d",&k);
  109.         for ( j=0 ; j<k ; j++ )
  110.         {
  111.             scanf("%I64d",&d );
  112.             hash[d/100].push_back(d);
  113.             ins(d/100,head);
  114.         }
  115.         maxnum=max(head);
  116.         minnum=min(head);
  117.         res+=hash_max(maxnum)-hash_min(minnum);
  118.         del(maxnum,head);
  119.         del(minnum,head);
  120.     }
  121.     printf("%I64d/n",res);
  122. }
剛開始接觸線段樹,還不會離散化~繼續學習。。。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章