CF1659D (思维 树状数组)

  • 数组A中的每个1被统计了n次,所以可以得到A中1的个数
  • 倒着模拟,就知道了Bi数组(1都在后面),当前bi>=i说明Ai = 1,bi是由bi-1在[i - one + 1, i]上加1得来的,所以让这个区间全减一,bi < i则Ai = 0,bi由bi-1右移动得来。
  • 树状数组维护差分数组,实现区间修改,单点查询
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0);  
//#pragma GCC optimize(3,"Ofast","inline")
#define ll long long
const int N = 2e5 + 5;
const int mod = 998244353;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1.0);
ll a[N], tree[N];int n, ans[N]; 
int lowbit (int x) { return (-x) & x;}
ll query(int i) {
   ll sum = 0;
   for (; i; i -= lowbit(i) ) sum += tree[i];
   return sum;
}
void update(int l, int r, ll val) {
   for (int i = l; i <= n ; i += lowbit(i) ) tree[i] +=  val;
   for (int i = r + 1; i <= n ; i += lowbit(i)  ) tree[i] -= val;
}
void solve() {
   cin >> n;
   ll one = 0;
   memset(tree, 0, sizeof tree);
   for ( int i = 1; i <= n; ++ i ) cin >> a[i], one += a[i], ans[i] = 0, update(i, i, a[i]);
   one /= n;
   for ( int i = n; i >= 1; -- i ) {
       
       if(query(i) >= i)  update(i - one + 1, i, -1), -- one, ans[i] = 1;

   }
   for (int i = 1; i <= n; i++) cout << ans[i] << " ";

   cout << endl;
}
int main () {
   IOS
   int t; cin >> t;
   while(t --) solve();
   return 0;
}
posted @ 2022-04-20 15:24  qingyanng  阅读(22)  评论(0编辑  收藏  举报