luogu P7603 [THUPC2021] 鬼街

https://www.luogu.com.cn/problem/P7603

gym 102331 F. Fast Spanning Tree 这题一样的套路

把监控事件的\(y\)平均分配到每个管辖的区域里,作为其中一个阈值限制,然后每次加的时候如果有一个点碰到阈值就暴力把剩下的重新分配。

假设管辖的区域不超过\(6\)个,因为每次碰到阈值,至少会让阈值减少\(\frac{1}{6}\),也就是说至少会变为原来的\(\frac{5}{6}\),容易得到时间复杂度为
\(O(6nlognlog_{\frac{6}{5}}y)\)

代码实现不难

code:

#include<bits/stdc++.h>
#define fi first
#define se second
#define ll long long
#define N 400050
using namespace std;
vector<int> d[N], ans;
void init(int n) {
    for(int i = 2; i <= n; i ++) if(!d[i].size()) 
        for(int j = i; j <= n; j += i) d[j].push_back(i);
}
int sz, ha[N], ban[N];
ll lim[N], a[N];
priority_queue<pair<ll, int> > q[N];
void add(int u, ll o) {
    a[u] += o;
    while(q[u].size()) {
        auto x = q[u].top(); q[u].pop();
        if(ban[x.se]) continue;
        if(- x.fi <= a[u]) {    
            int gs = 0; ll s = 0;
            for(int y : d[ha[x.se]]) gs ++, s += a[y];

            if(s >= lim[x.se]) ban[x.se] = 1, ans.push_back(x.se);
            else {
                ll o = (lim[x.se] - s - 1) / gs + 1;
                for(int y : d[ha[x.se]]) q[y].push(make_pair(- (a[y] + o), x.se));
            }            
        } else {
            q[u].push(x); break;
        }
    }
}
int n, m;
int main() {
    // freopen("a.in","r",stdin);
    // freopen("a.out","w",stdout);
    scanf("%d%d", &n, &m); init(n);
    int lst = 0;
    while(m --) {
        int o, x; ll y;
        scanf("%d%d%lld", &o, &x, &y); y ^= lst;
        if(!o) {
            for(int it : d[x]) add(it, y);
            sort(ans.begin(), ans.end());
            lst = ans.size();
            printf("%d ", lst);
            for(int x : ans) printf("%d ", x); printf("\n"); 
            vector<int> xx; xx.clear();
            ans.swap(xx);
        } else {
            ++ sz; lim[sz] = y; ha[sz] = x;
            if(!y) {ans.push_back(sz); continue;}
            int gs = 0; ll s = 0;
            for(int y : d[x]) gs ++, lim[sz] += a[y], s += a[y];
            ll o = (lim[sz] - s - 1) / gs + 1;
            for(int y : d[x]) q[y].push(make_pair(- (a[y] + o), sz));
        }
    }
    return 0;
}

posted @ 2022-02-25 22:13  lahlah  阅读(158)  评论(0编辑  收藏  举报