码迷,mamicode.com
首页 > 其他好文 > 详细

Petrozavodsk Summer Training Camp 2016H(多标记线段树)题解

时间:2019-10-02 22:34:42      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:pac   summer   build   i++   高度   sum   sort   vector   inline   

题意:

\(n\)个草,第\(0\)天种下,高度都为\(0\),每个草每天长高\(a_i\)。现给出\(q\)询问,每次给出第\(b\)天,然后把高于\(d\)的全削成\(d\),每次问你削下来的高度是多少。

思路:

能看出草的顺序和答案无关,那么按\(a_i\)排序,后面的草永远都比前面的高。然后线段树维护区间加,区间重置,区间询问。

代码:

#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;
}

Petrozavodsk Summer Training Camp 2016H(多标记线段树)题解

标签:pac   summer   build   i++   高度   sum   sort   vector   inline   

原文地址:https://www.cnblogs.com/KirinSB/p/11618662.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!