您的位置:首页 > 其它

ZOJ 3635 Cinema in Akiba (树状数组+二分)

2014-04-01 14:33 211 查看
//460ms
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define low(x) x&(-x)
int c[100005],ans[100005],n;
void add(int i,int val)
{
while(i<=n)
{
c[i]+=val;
i+=low(i);
}
}
int getsum(int i)
{
int sum=0;
while(i>0)
{
sum+=c[i];
i-=low(i);
}
return sum;//getsum(i)表示该位置前(包括)还有多少空位
}
int main()
{
int i;
while(scanf("%d",&n)!=EOF)
{
memset(c,0,sizeof(c));
memset(ans,0,sizeof(ans));
for(i=1;i<=n;i++)add(i,1);
for(i=1;i<=n;i++)
{
int mid,p;
scanf("%d",&p);
int r=n,l=1;
while(r>l)
{
mid=(r+l)/2;
//if(i==5)printf("===%d\n",mid);
if(getsum(mid)>=p)r=mid;//有重复值时向前找第一个
else l=mid+1;
}
ans[i]=r;
add(r,-1);
/*
一开始不是这样写的,wa到死!
错误代码:
while(l<=h)
{
int mid=(l+h)/2;
printf("mid=%d\n",mid);
if(p<getsum(mid)){
h=mid-1;
}
else if(p>getsum(mid))l=mid+1;
else
{
ans[i]=mid;
add(mid,-1);
// printf("--%d\n",mid);
break;
}
}
*/
}
int m;
scanf("%d",&m);;
while(m--)
{
int x;
scanf("%d",&x);
if(m)printf("%d ",ans[x]);
else printf("%d\n",ans[x]);
}

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: