hdu4217

这个代码超时了,不知道为什么会这样,已经用了线段树啊

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int pos;
 6 
 7 int tree[600000];
 8 void build(int left ,int right ,int i)
 9 {
10     tree[i]=right-left+1;
11     if(left==right)
12     {
13         return;
14     }
15     int mid=(left+right)/2;
16     build(left,mid,2*i);
17     build(mid+1,right,2*i+1);
18 
19 }
20 void  Update(int p,int left ,int right ,int i)
21 {
22     tree[i]--;
23     if(left==right)
24     {
25         pos=left;
26         return ;
27     }
28     int mid=(left+right)/2;
29     if(p<=tree[2*i])//p<=mid不可以,因为tree[]时刻在更新
30     {
31         Update(p,left,mid,2*i);
32     }
33     /*if (p>tree[2*i])//注意这里千万不能这样写,因为这里有可能会出现一个很隐蔽的错误,当执行上面的Update(p,left,mid,2*i);修改了tree[]的值,所以这里就有可能成立,隐蔽啊隐蔽
34     {
35         p=p-tree[2*i];
36         Update(p,mid+1,right,2*i+1);
37     }*/
38     else
39     {
40         p=p-tree[2*i];
41         Update(p,mid+1,right,2*i+1);
42     }
43 }
44 int main()
45 {
46     int Case;
47     cin>>Case;
48     int n,m;
49     int i,p;
50     int k=1;
51     while(Case--)
52     {
53         cin>>n>>m;
54         build(1,n,1);
55         int sum=0;
56         for(i=0;i<m;i++)
57         {
58             cin>>p;
59             Update(p,1,n,1);
60             sum=sum+pos;
61         }
62         cout<<"Case "<<k++<<": ";
63         cout<<sum<<endl;
64     }
65     return 0;
66 }

 

等有时间再用c重写一遍吧

这里贴一个能用的

 1 #include <stdio.h>
 2  
 3 const int MAXN=262144;
 4  
 5 int tree[MAXN<<1];
 6  
 7 int pos;
 8  
 9 void build(int l,int r,int rt)
10 {
11     tree[rt]=r-l+1;//表示节点含有的数据个数
12  
13     if(r==l)
14         return ;
15  
16     int m=(r+l)/2;
17  
18     build(l,m,rt*2);
19     build(m+1,r,rt*2+1);
20 }
21  
22 void update(int p,int l,int r,int rt)
23 {
24     tree[rt]--;//更新节点的数的个数
25  
26     if(r==l)
27     {
28         pos=l;//此时的pos代表第几个最小值
29         return ;
30     }
31  
32     int m=(r+l)/2;
33  
34     if(p<=tree[rt*2])//搜索所需改变的节点
35         update(p,l,m,rt*2);
36     else
37     {
38         p-=tree[rt*2];
39         update(p,m+1,r,rt*2+1);
40     }
41 }
42  
43 int main()
44 {
45     int t,k,n,ks,tn=1; 
46  
47     __int64 sum;
48  
49     scanf("%d",&t);
50  
51     while(t--)
52     {
53         sum=0;
54  
55         scanf("%d%d",&n,&k);
56  
57         build(1,n,1);
58  
59         for(int i=0;i<k;i++)
60         {
61             scanf("%d",&ks);
62  
63             update(ks,1,n,1);
64  
65             sum+=pos;
66         }
67  
68         printf("Case %d: %I64d\n",tn++,sum);
69     }
70  
71     return 0;
72 }

算是按照别人的抄的都没过,汗啊

又修改了两个地方,终于AC了

第一个重新用C写了一遍,第二把sum改成了__int64就行了

 1 #include <stdio.h>
 2 
 3 
 4 
 5 int pos;
 6 
 7 int tree[600000];
 8 void build(int left ,int right ,int i)
 9 {
10     tree[i]=right-left+1;
11     if(left==right)
12     {
13         return;
14     }
15     int mid=(left+right)/2;
16     build(left,mid,2*i);
17     build(mid+1,right,2*i+1);
18 
19 }
20 void  Update(int p,int left ,int right ,int i)
21 {
22     tree[i]--;
23     if(left==right)
24     {
25         pos=left;
26         return ;
27     }
28     int mid=(left+right)/2;
29     if(p<=tree[2*i])//p<=mid不可以,因为tree[]时刻在更新
30     {
31         Update(p,left,mid,2*i);
32     }
33     /*if (p>tree[2*i])//注意这里千万不能这样写,因为这里有可能会出现一个很隐蔽的错误,当执行上面的Update(p,left,mid,2*i);修改了tree[]的值,所以这里就有可能成立,隐蔽啊隐蔽
34     {
35         p=p-tree[2*i];
36         Update(p,mid+1,right,2*i+1);
37     }*/
38     else
39     {
40         p=p-tree[2*i];
41         Update(p,mid+1,right,2*i+1);
42     }
43 }
44 int main()
45 {
46     int Case;
47     scanf("%d",&Case);
48     int n,m;
49     int i,p;
50     int k=1;
51     while(Case--)
52     {
53         scanf("%d%d",&n,&m);
54         build(1,n,1);
55         __int64 sum=0;
56         for(i=0;i<m;i++)
57         {
58             scanf("%d",&p);
59             Update(p,1,n,1);
60             sum=sum+pos;
61         }
62         printf("Case %d: %I64d\n",k++,sum);
63     }
64     return 0;
65 }

posted on 2012-08-02 22:18  矮人狙击手!  阅读(262)  评论(0编辑  收藏  举报

导航