CF782-D Reverse Sort Sum


Reverse Sort Sum

法1:首先可得数组A中的1的总个数,对于\(f(i,A)\),如果前\(i\)位有\(x\)个1,那么数组C的\([i - x + 1, i]\)区间会+1,所以考虑反向操作,让区间-1,然后从后往前推(每次将Bi的贡献从Ci中删除),然后遍历到\(C_i\)时,如果大于0则\(A_{i}\)为1。区间修改可以利用类似于懒标记删除的东西得到\(O(n)\)做法。

#include
#include

using namespace std;
using ll = long long;

int main()
{
    int T; cin >> T;
    while(T--){
        int n; cin >> n;
        vectora(n + 1), res(n), lazy(n + 1); //类似于懒标记删除
        
        for(int i = 1; i <= n; ++i) cin >> a[i];
        
        ll num = 0;
        for(int i = 1; i <= n; ++i) num += a[i];
        num /= n; // 1的个数
        
        int tmp = 0; // 累计需要扣去的数
        
        for(int i = n; i >= 1 && num; --i) {
            tmp --;
            lazy[i - num] ++;
            tmp += lazy[i];
            if(a[i] + tmp > 0) res[i - 1] = 1, num --;
        }
        
        if(num == 1) res[0] = 1;
        
        for(auto x : res) cout << x << " ";
        cout << endl;
    }
    
    return 0;
}

法2:利用树状数组进行区间修改,思路同法1,\(O(nlogn)\)

#include
#include
#include

using namespace std;
using ll = long long;

int n;
int tr[200010];

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

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

ll query(int x){
    ll res = 0;
    for(int i = x; i; i -= lowbit(i)) res += tr[i];
    return res;
}

int main()
{
    int T; cin >> T;
    while(T--){
        cin >> n;
        
        memset(tr, 0, sizeof tr);
        
        vectora(n + 1), d(n + 1), res(n);
        
        for(int i = 1; i <= n; ++i) cin >> a[i];
        
        for(int i = 1; i <= n; ++i) d[i] = a[i] - a[i - 1];
        
        for(int i = 1; i <= n; ++i) add(i, d[i]);
        
        ll num = 0;
        for(int i = 1; i <= n; ++i) num += a[i];
        num /= n; // 1的个数
        
        for(int i = n; i >= 1 && num; --i) {
            add(i - num + 1, -1);
            add(i + 1, 1);
            if(query(i)) res[i - 1] = 1, num --;
        }
        
        if(num == 1) res[0] = 1;
        
        for(auto x : res) cout << x << " ";
        cout << endl;
    }
    
    return 0;
}

相关