Petrozavodsk Summer Training Camp 2016H (multi-label segment tree) solution to a problem

Meaning of the questions:

\ (n \) th grass, the \ (0 \) next day species are highly \ (0 \) , each grass grow taller every day \ (a_i \) . Now gives \ (q \) asked each to give the first \ (b \) days, then the above \ (d \) full whittled \ (d \) , each time asking you to cut down the height How many.

Ideas:

The answer has nothing to do and the order can see the grass, then press \ (a_i \) sort, behind the grass is always better than the previous high. Then add segment tree maintenance interval, reset interval, the interval inquiry.

Code:

#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<bitset>
#include<string>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 5e5 + 5;
const int M = 50 + 5;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const ll MOD = 1000000007;

#define lson (rt << 1)
#define rson (rt << 1 | 1)
int n, m;
ll sum[maxn << 2], sumW[maxn << 2], Mw[maxn << 2], Max[maxn << 2];
ll t[maxn << 2], reset[maxn << 2];
//时间戳,重置
ll a[maxn];
void pushup(int rt){
    sum[rt] = sum[lson] + sum[rson];
    Max[rt] = Max[rson];
    Mw[rt] = Mw[rson];
    sumW[rt] = sumW[lson] + sumW[rson];
}
void pushdown(int rt, int l, int r){
    int m = (l + r) >> 1;
    if(reset[rt] != -1){
        reset[lson] = reset[rt];
        reset[rson] = reset[rt];
        t[lson] = 0;
        t[rson] = 0;
        Max[lson] = reset[rt];
        Max[rson] = reset[rt];
        sum[lson] = 1LL * reset[rt] * (m - l + 1);
        sum[rson] = 1LL * reset[rt] * (r - m);
        reset[rt] = -1;
    }
    if(t[rt]){
        sum[lson] += t[rt] * sumW[lson];
        sum[rson] += t[rt] * sumW[rson];
        Max[lson] += t[rt] * Mw[lson];
        Max[rson] += t[rt] * Mw[rson];
        t[lson] += t[rt];
        t[rson] += t[rt];
        t[rt] = 0;
    }
}
void build(int l, int r, int rt){
    t[rt] = 0;
    reset[rt] = -1;
    if(l == r){
        sumW[rt] = Mw[rt] = a[l];
        sum[rt] = Max[rt] = 0;
        return;
    }
    int m = (l + r) >> 1;
    build(l, m, lson);
    build(m + 1, r, rson);
    pushup(rt);
}
void _set(int L, int R, int l, int r, ll v, int rt){
    if(L <= l && R >= r){
        sum[rt] = 1LL * v * (r - l + 1);
        reset[rt] = v;
        Max[rt] = v;
        t[rt] = 0;
        return;
    }
    pushdown(rt, l, r);
    int m = (l + r) >> 1;
    if(L <= m)
        _set(L, R, l, m, v, lson);
    if(R > m)
        _set(L, R, m + 1, r, v, rson);
    pushup(rt);
}
void add(int L, int R, int l, int r, ll v, int rt){
    if(L <= l && R >= r){
        sum[rt] += sumW[rt] * v;
        t[rt] += v;
        Max[rt] += Mw[rt] * v;
        return;
    }
    pushdown(rt, l, r);
    int m = (l + r) >> 1;
    if(L <= m)
        add(L, R, l, m, v, lson);
    if(R > m)
        add(L, R, m + 1, r, v, rson);
    pushup(rt);
}
ll querysum(int L, int R, int l, int r, int rt){
    if(L <= l && R >= r){
        return sum[rt];
    }
    pushdown(rt, l, r);
    int m = (l + r) >> 1;
    ll ret = 0;
    if(L <= m)
        ret += querysum(L, R, l, m, lson);
    if(R > m)
        ret += querysum(L, R, m + 1, r, rson);
    return ret;
}
int queryMore(int l, int r, ll v, int rt){
    if(l == r){
        return Max[rt] > v? l : -1;
    }
    pushdown(rt, l, r);
    int m = (l + r) >> 1;
    if(Max[lson] > v)
        return queryMore(l, m, v, lson);
    else
        return queryMore(m + 1, r, v, rson);
}
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    sort(a + 1, a + n + 1);
    build(1, n, 1);
    ll u, v, pre = 0;
    while(m--){
        scanf("%lld%lld", &u, &v);
        add(1, n, 1, n, u - pre, 1);
        int pos = queryMore(1, n, v, 1);
        if(pos == -1) puts("0");
        else{
            ll ret = querysum(pos, n, 1, n, 1);
            ret = ret - 1LL * v * (n - pos + 1);
            printf("%lld\n", ret);
            _set(pos, n, 1, n, v, 1);
        }
        pre = u;
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/KirinSB/p/11618662.html