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 }