--- 这里是 cjiaw 的小窝(●'◡'●) ---

正在玩命加载中......

AcWing 244. 谜一样的牛(树状数组)

题目链接:244. 谜一样的牛 - AcWing题库


题目大意:

有 n 头奶牛,已知它们的身高为 1n 且各不相同,但不知道每头奶牛的身高。

现在这 n 头奶牛站成一列,已知第 i 头牛前面有 Ai 头牛比它低,

求每头奶牛的身高。


思路:

把题目看成

从后往前删除数,

每次删除后求第k小的数的位置


代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define  mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;

const int N = 200086, mod = 998244353;

int n, m;
int a[N];
int s[N];
stack<int >q;

int lowbit(int x) {
    return x & -x;
}

void add(int i, int x) {
    for (; i <= n; i += lowbit(i)) s[i] += x;
}

int sum(int i) {
    int res = 0;
    for (; i; i -= lowbit(i)) res += s[i];
    return res;
}

void solve() {

    cin >> n;
    for (int i = 2; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= n; i++) add(i, 1);
    
    for (int i = n; i; i--) {
        int h = a[i] + 1;
        int l = 0, r = n + 1;
        while (l + 1 < r) {
            int mid = l + r >> 1;
            if (sum(mid) >= h) r = mid;
            else l = mid;
        }
        
        q.push(r);
        add(r, -1);
    }
    
    while (q.size()) {
        cout << q.top() << endl;
        q.pop();
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    
    int T = 1;
// cin >> T;
    while (T--) solve();
    
    return 0;
}

 

posted @ 2025-10-29 22:00  wwjjw  阅读(15)  评论(0)    收藏  举报