ZOJ 3635 Cinema in Akiba(樹狀陣列 + 二分)
阿新 • • 發佈:2019-01-27
題意:
有 n 個位置,從小到大分別編號為 1~n。然後有 n 次操作,每次取第 Ki 個沒有被取到的編號,最後詢問某次操作取出的是誰。
解題思路:
用 sum(i) 記錄 1~i 位置中,一共有幾個空座位。每次二分找到第 Ki 個是哪一個,然後將這個位置 th~n 全部減一。
#include <vector> #include <string> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N = 5e4 + 5; int c[N],ans[N]; int lowbit(int x) { return x & -x; } void add(int loc,int x) { while(loc < N) { c[loc] += x; loc += lowbit(loc); } } int sum(int loc) { int ret = 0; while(loc) { ret += c[loc]; loc -= lowbit(loc); } return ret; } int main() { int n; while(~scanf("%d",&n)) { memset(c,0,sizeof(c)); for(int i=1;i<=n;i++) add(i,1); for(int i=1;i<=n;i++) { int k; scanf("%d",&k); int l = 1 , r = n; while(l < r) { int mid = l+r >> 1; if(sum(mid) < k) l = mid + 1; else r = mid; } ans[i] = r; add(r,-1); } int Q,m; scanf("%d",&Q); while(Q--) { scanf("%d",&m); printf("%d%c",ans[m],Q?' ':'\n'); } } return 0; }