CF Round #782 D - Reverse Sort Sum
阿新 • • 發佈:2022-05-12
D - Reverse Sort Sum
線段樹 / 樹狀陣列
從後往前遍歷,如果 c[i] = i, 則說明第 i 個位置上的 1 是從時刻1到 時刻 i 都存在的,所以這一位最開始就是 1,此時若前 i 位有 k 個 1,它們一定在 [i - k + 1, i] 位置上,這個區間 - 1,這是第 i 位的 1 被永遠留在這一位了,所以 k--;
否則 k 不減 1,其餘操作一樣
#include <iostream> #include <cstring> #include <algorithm> #include <vector> using namespace std; typedef long long ll; const int N = 2e5 + 10; int n; int c[N], tr[N]; int ans[N]; int lowbit(int x) { return x & -x; } void add(int idx, int k) { for (int i = idx; i <= n; i += lowbit(i)) tr[i] += k; } void modify(int l, int r, int k) { add(l, k); add(r + 1, -k); } int query(int idx) { int ans = 0; for (int i = idx; i; i -= lowbit(i)) ans += tr[i]; return ans; } int main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int T; cin >> T; while(T--) { cin >> n; fill(tr, tr + n + 2, 0); ll sum = 0; for (int i = 1; i <= n; i++) { cin >> c[i]; sum += c[i]; modify(i, i, c[i]); } int k = sum / n; for (int i = n; i >= 1; i--) { int t = query(i); int sub = 0; if (t == i) { ans[i] = 1; sub++; } else ans[i] = 0; int r = i, l = r - k + 1; modify(l, r, -1); k -= sub; } for (int i = 1; i <= n; i++) cout << ans[i] << " "; cout << endl; } return 0; }