• 【线段树】结训赛— H


    • Step1 Problem

    原题
    一个人有很多家公司给他了offer,但是他看了看觉得薪水都太低了,并不想参加,于是决定回家种地。(任性啊,这个人)
    他在家里开始种西瓜,家里一共有n块瓜田,每年可以产出ai个西瓜。每年亮皇回家的时候都会看看他种的这块地,他会做以下下两种操作之一:
    1、询问一段土地从第一年开始,到当年结束一共生产了多少个西瓜。
    2、在一段土地上种上黄豆,这样可以让这块西瓜地从下一年开始产量+1。(种豆得瓜?)
    某人一共会回家m年,请你帮他回答所有的查询。

    • Step2 Ideas:

    这题需要你求出从第一年开始一共生产的瓜,那就恶心了,一个线段树的裸题硬生生成了个送命题(只是对我来说),那问题在于怎么去维护线段树的区间信息,一开始想维护总产量,写到后面又出现了不好加去年产量的问题,又想用map去存他是第几年更新的这个点,尴尬在于不会用map<int, pair<int, int> > ,STL还是太菜,又然后、、、、就想到了用两棵树去做了,一棵树就单纯的维护单产,又一棵树去维护这个区间在第几年加了buff,然后最终的答案就可以写为 总产 = 单产*年数 - 修改他的年份。(顺便吐槽一下自己,想到一个方法因为没有写过两个线段树的题就不敢写?如果敢于动键盘顺着思路下去没什么难的,还有就是这STL真的太菜了,虽然我用map的想法不一定对,但死在不会用上就很难受了。。)

    • Step3 Code:
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    #include<stack>
    #include<queue>
    #include<map>
    #define lt k<<1
    #define rt k<<1|1
    using namespace std;
    typedef long long ll;
    const ll N = 1e5+5;
    const int inf = 0x3f3f3f3f;
    struct node
    {
        ll ltree, rtree;
        ll sum, lazy;
    } tree[N<<2], tree1[N<<2];
    ll n, q, ans[N];
    
    void pushdown(node *tree, ll k)
    {
        tree[lt].sum += tree[k].lazy * (tree[lt].rtree - tree[lt].ltree + 1);
        tree[rt].sum += tree[k].lazy * (tree[rt].rtree - tree[rt].ltree + 1);
        tree[lt].lazy += tree[k].lazy, tree[rt].lazy += tree[k].lazy;
        tree[k].lazy = 0;
    }
    
    void build(node *tree, ll l, ll r, ll k, ll pos)
    {
        tree[k].ltree = l, tree[k].rtree = r;
        tree[k].lazy = 0;
        if(l == r)
        {
            if(pos) cin >> tree[k].sum;
            else tree[k].sum = 0;
            return ;
        }
        ll mid = (l + r)>>1;
        build(tree, l, mid, lt, pos);
        build(tree, mid+1, r, rt, pos);
        tree[k].sum = tree[lt].sum + tree[rt].sum;
    }
    
    ll query(node *tree, ll l, ll r, ll k)
    {
        ll L = tree[k].ltree, R = tree[k].rtree;
        if(l <= L && r >= R) return tree[k].sum;
        if(tree[k].lazy) pushdown(tree, k);
        ll mid = (L + R)>>1;
        if(r <= mid) return query(tree, l, r, lt);
        else if(l > mid) return query(tree, l, r, rt);
        else return query(tree, l, mid, lt) + query(tree, mid+1, r, rt);
    }
    
    void uptade(node *tree, ll l, ll r, ll k, ll num)
    {
        ll L = tree[k].ltree, R = tree[k].rtree;
        if(L == l && R == r)
        {
            tree[k].sum += (R - L + 1)*num;
            tree[k].lazy += num;
            return ;
        }
        if(tree[k].lazy) pushdown(tree, k);
        ll mid = (L + R)>>1;
        if(mid >= r) uptade(tree, l, r, lt, num);
        else if(mid < l) uptade(tree, l, r, rt, num);
        else
        {
            uptade(tree, l, mid, lt, num);
            uptade(tree, mid+1, r, rt, num);
        }
        tree[k].sum = tree[lt].sum + tree[rt].sum;
    }
    
    
    int main()
    {
        ios::sync_with_stdio(false);
        while(cin >> n)
        {
            build(tree, 1, n, 1, 1);
            build(tree1, 1, n, 1, 0);
            char c;
            cin >> q;
            ll tot = 0;
            for(ll i = 1; i <= q; i++)
            {
                cin >> c;
                if(c == 'Q')
                {
                    ll a, b;
                    cin >> a >> b;
                    ll sum = query(tree, a, b, 1);
                    ll sum1 = query(tree1, a, b, 1);
                    ans[tot++] = sum*i - sum1;
                }
                else
                {
                    ll a, b;
                    cin >> a >> b;
                    uptade(tree, a, b, 1, 1);
                    uptade(tree1, a, b, 1, i);
                }
            }
            for(ll i = 0; i < tot; i++)
            {
                if(!i) cout << ans[i];
                else cout << ' ' << ans[i];
            }
            cout << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    poj3255,poj2449
    poj2186
    poj3249
    poj3378
    poj3274
    poj1948
    hdu 2181暴搜
    hdu 3342
    hdu 1285
    hdu 1598
  • 原文地址:https://www.cnblogs.com/zyysyang/p/11093496.html
Copyright © 2020-2023  润新知