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; }
相关文章推荐
- zoj 3635 Cinema in Akiba(树状数组+二分)
- ZOJ 3635——Cinema in Akiba(树状数组+二分)
- ZOJ 3635 Cinema in Akiba(树状数组 + 二分)
- ZOJ3635——Cinema in Akiba(树状数组+二分)
- ZOJ 3635 Cinema in Akiba[ 块状数组 ]
- ZOJ 3635 Cinema in Akiba(二分+树状数组)
- zoj 3635 Cinema in Akiba 二分+树状数组
- zoj 3635 树状数组加二分
- Poj 2828 Buy Tickets \ Zoj 3635 Cinema in Akiba
- ZOJ 3635 Cinema in Akiba
- ZOJ 题目3635 Cinema in Akiba(线段树插空)
- ZOJ-3635-Cinema in Akiba
- Zoj 3635 <树状数组+二分>
- ZOJ 3635 Cinema in Akiba
- ZOJ 3635 Cinema in Akiba【树状数组+二分查找】
- ZOJ 3635 Cinema in Akiba(线段树)
- ZOJ 3635 Cinema in Akiba(线段树)
- ZOJ 3635 Cinema in Akiba[ 大规模阵列 ]
- zoj 3635 Cinema in Akiba
- ZOJ 3635 Cinema in Akiba (第一次组队) 树状数组+二分