您现在的位置: 中国男护士网 >> 考试频道 >> 计算机等级 >> 二级辅导 >> C十十 >> 辅导 >> 正文    
  C++基础(线段树学习) 【注册男护士专用博客】          

C++基础(线段树学习)

www.nanhushi.com     佚名   不详 

  一个线段树的题,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 nonnegative 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 ith 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


  代码
  #include<iostream>
  #include<vector>
  using namespace std;
  const __int64 MAXN = 10000;
  struct NODE
  {
  __int64 l,r,cnt;
  NODE *left_child,*right_child;
  };
  vector<__int64> hash[10001];
  void build ( NODE *v , __int64 l , __int64 r )
  {
  NODE *p;
  __int64 m;
  if ( l>=r )
  return ;
  m=(l+r)>>1;
  p=new NODE;
  p>l=l,p>r=m,p>cnt=0,p>left_child=p>right_child=NULL;
  v>left_child=p;
  build(p,l,m);
  p=new NODE;
  p>l=m+1,p>r=r,p>cnt=0,p>left_child=p>right_child=NULL;
  v>right_child=p;
  build(p,m+1,r);
  }
  void ins ( __int64 d , NODE *v )
  {
  __int64 m;
  if ( v==NULL )
  return;
  if ( v>l<=d && d<=v>r )
  {
  v>cnt++;
  m=(v>l+v>r)/2;
  if ( d<=m )
  ins(d,v>left_child);
  else
  ins(d,v>right_child);
  }
  }
  void del ( __int64 d , NODE *v )
  {
  __int64 m;
  if ( v==NULL )
  return;
  if ( v>l<=d && d<=v>r )
  {
  if ( v>cnt>0 )
  v>cnt;
  m=(v>l+v>r)/2;
  if ( d<=m )
  del(d,v>left_child);
  else
  del(d,v>right_child);
  }
  }
  __int64 max ( NODE *v )
  {
  if ( v>left_child==NULL ||v>right_child==NULL )
  return v>r;
  if ( v>right_child>cnt )
  return max(v>right_child);
  else
  return max(v>left_child);
  }
  __int64 min ( NODE *v )
  {
  if ( v>left_child==NULL ||v>right_child==NULL )
  return v>l;
  if ( v>left_child>cnt )
  return min(v>left_child);
  else
  return min(v>right_child);
  }
  __int64 hash_max ( __int64 f )
  {
  vector<__int64>::iterator p,q;
  __int64 res;
  for ( p=q=hash[f].begin() ; p!=hash[f].end() ; p++ )
  if( *q<*p )
  q=p;
  res=*q;
  hash[f].erase(q);
  return res;
  }
  __int64 hash_min ( __int64 f )
  {
  vector<__int64>::iterator p,q;
  __int64 res;
  for ( p=q=hash[f].begin() ; p!=hash[f].end() ; p++ )
  if( *q>*p )
  q=p;
  res=*q;
  hash[f].erase(q);
  return res;
  }
  int main ( )
  {
  NODE *head;
  __int64 c,k,i,j,d,maxnum,minnum,res=0;
  head=new NODE;
  head>cnt=0,head>l=0,head>r=MAXN,head>left_child = head>right_child = NULL;
  build(head,0,MAXN);
  scanf("%I64d",&c);
  for ( i=0 ; i<c ; i++ )
  {
  scanf("%I64d",&k);
  for ( j=0 ; j<k ; j++ )
  {
  scanf("%I64d",&d );
  hash[d/100].push_back(d);
  ins(d/100,head);
  }
  maxnum=max(head);
  minnum=min(head);
  res+=hash_max(maxnum)hash_min(minnum);
  del(maxnum,head);
  del(minnum,head);
  }
  printf("%I64d\n",res);
  }
  刚开始接触线段树,还不会离散化~继续学习。

 

文章录入:杜斌    责任编辑:杜斌 
  • 上一篇文章:

  • 下一篇文章:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
     

    联 系 信 息
    QQ:88236621
    电话:15853773350
    E-Mail:malenurse@163.com
    免费发布招聘信息
    做中国最专业男护士门户网站
    最 新 热 门
    最 新 推 荐
    相 关 文 章
    没有相关文章
    专 题 栏 目

      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)                            【进男护士社区逛逛】
    姓 名:
    * 游客填写  ·注册用户 ·忘记密码
    主 页:

    评 分:
    1分 2分 3分 4分 5分
    评论内容:
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。