Codeforces 609F Frogs and mosquitoes 线段树

Frogs and mosquitoes

用线段树维护每个点覆盖的最小id, 用multiset维护没有吃的蚊子。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long

using namespace std;

const int N = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-6;
const double PI = acos(-1);

struct Forg {
    int x, cnt, id;
    LL t;
    bool operator < (const Forg& rhs) const {
        return x < rhs.x;
    }
    void print() {
        printf("id: %d  x: %d  cnt: %d  t: %lld\n", id, x, cnt, t);
    }
};

int n, m;
Forg frog[N];
PII mos[N];

LL anst[N], ansc[N];

vector<LL> oo;
multiset<PII> uneat;

int getPosL(LL x) {
    return lower_bound(oo.begin(), oo.end(), x) - oo.begin() + 1;
}
int getPosR(LL x) {
    return upper_bound(oo.begin(), oo.end(), x) - oo.begin();
}


namespace SGT {
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
    int a[N << 2];
    void init() {
        memset(a, inf, sizeof(a));
    }
    void update(int L, int R, int val, int l, int r, int rt) {
        if(L > R) return;
        if(l >= L && r <= R) {
            a[rt] = min(a[rt], val);
            return;
        }
        int mid = l + r >> 1;
        if(L <= mid) update(L, R, val, lson);
        if(R > mid)  update(L, R, val, rson);
    }
    int query(int p, int l, int r, int rt) {
        if(l == r) return a[rt];
        int mid = l + r >> 1;
        if(p <= mid) return min(a[rt], query(p, lson));
        else return min(a[rt], query(p, rson));
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%d%lld", &frog[i].x, &frog[i].t);
        frog[i].id = i;
    }
    sort(frog + 1, frog + 1 + n);
    for(int i = 1; i <= m; i++) {
        scanf("%d%d", &mos[i].fi, &mos[i].se);
        oo.push_back(mos[i].fi);
    }
    sort(oo.begin(), oo.end());
    oo.erase(unique(oo.begin(), oo.end()), oo.end());
    SGT::init();
    for(int i = 1; i <= n; i++) {
        SGT::update(getPosL(frog[i].x), getPosR(frog[i].x + frog[i].t), i, 1, SZ(oo), 1);
    }
    for(int i = 1; i <= m; i++) {
        int p = mos[i].fi, b = mos[i].se;
        int who = SGT::query(getPosL(p), 1, SZ(oo), 1);
        if(who < inf) {
            LL pre = frog[who].x + frog[who].t;
            frog[who].t += b;
            frog[who].cnt++;
            LL now = frog[who].x + frog[who].t;
            SGT::update(getPosL(pre + 1), getPosR(now), who, 1, SZ(oo), 1);
            while(SZ(uneat)) {
                auto it = uneat.lower_bound(mk(pre + 1, -inf));
                if(it == uneat.end()) break;
                who = SGT::query(getPosL(it->fi), 1, SZ(oo), 1);
                if(who >= inf) break;
                frog[who].t += it->se;
                frog[who].cnt++;
                now = frog[who].x + frog[who].t;
                SGT::update(getPosL(pre + 1), getPosR(now), who, 1, SZ(oo), 1);
                uneat.erase(it);
            }
        } else {
            uneat.insert(mos[i]);
        }
    }
    for(int i = 1; i <= n; i++)
        anst[frog[i].id] = frog[i].t, ansc[frog[i].id] = frog[i].cnt;
    for(int i = 1; i <= n; i++) printf("%lld %lld\n", ansc[i], anst[i]);
    return 0;
}

/*
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/10642526.html