zoukankan      html  css  js  c++  java
  • poj-3468

    等到我大脑已经残了,耳朵也鸣了,它终于过了。时间都哪去了,一天半就没了。

    这个题目有2个操作:修改一个区间的值(注意,它是把这个区间所有单位在原始值加上一个V值,并不是简单的直接改成V,所以在修改的时候,应该是累加,如:to[cur]+=V,而不是to[cur] = v),另外一个操作就是查询,这个题目主要运用了线段树,懒惰标记,因为它的查询是对一个区间进行的,若是对一个元结点进行查询,可以只用简单的线段树操作就OK了。看代码,此代码纠错机制由LH and TK大神倾力打造。

    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define maxn 300010
    #define LL long long
    using namespace std;
    int num[100010];
    LL to[maxn];
    LL ans;
    int read;
    
    struct H
    {
        int l,r;
        long long sum;
    } trees[maxn];
    
    void pushdown(int jd)
    {
        int mid = (trees[jd].l + trees[jd].r)/2;
        if(to[jd] != 0)
        {
            to[2*jd] += to[jd];
            to[2*jd+1] += to[jd];
            trees[2*jd].sum += (mid - trees[jd].l + 1) * to[jd];
            trees[2*jd + 1].sum += (trees[jd].r - mid) * to[jd];
            to[jd] = 0;
        }
    }
    
    void update(int jd)
    {
        trees[jd].sum = trees[2*jd].sum + trees[2 * jd + 1].sum;
    }
    
    void build_trees(int jd,int l,int r)
    {
        trees[jd].l=l;
        trees[jd].r=r;
        to[jd] = 0;
        if(l==r)
        {
            trees[jd].sum=num[l];
            return ;
        }
        int mid = (l+r)/2;
        build_trees(jd*2,l,mid);
        build_trees(jd*2+1,mid+1,r);
        update(jd);
    }
    void change(int jd,int s, int t, int v)
    {
        int mid = (trees[jd].l + trees[jd].r)/2;
        if(trees[jd].l >= s && trees[jd].r <= t)
        {
            to[jd]+=v;
            trees[jd].sum += (trees[jd].r - trees[jd].l + 1) * v;
            return ;
        }
        pushdown(jd);
        if(mid >= s)
            change(2*jd, s, t, v);
        if(t > mid)
            change(2*jd + 1,s, t, v);
        update(jd);
    }
    
    void query(int jd ,int l,int r)
    {
        if(l<=trees[jd].l&&r >=trees[jd].r)
        {
            ans += trees[jd].sum;
            return;
        }
        pushdown(jd);
        int mid = (trees[jd].l+trees[jd].r)/2;
        if(l<=mid) query(jd*2,l,r);
        if(r>mid) query(jd*2+1,l,r);
    }
    int main()
    {
        int n,m,l,r;
        char a;
        cin >> n >> m;
        for(int i = 1; i <= n; i++)
        {
            cin >> num[i];
        }
        build_trees(1,1,n);
        for(int i = 0; i < m; i++)
        {
            ans = 0;
            cin >> a;
            if(a == 'Q')
            {
                cin >> l >> r;
                query(1,l,r);
                cout << ans << endl;
            }
            if(a == 'C')
            {
                cin >> l >> r >> read;
                change(1,l,r,read);
            }
        }
        return 0;
    }
  • 相关阅读:
    hdu 4614 线段树 二分
    cf 1066d 思维 二分
    lca 最大生成树 逆向思维 2018 徐州赛区网络预赛j
    rmq学习
    hdu 5692 dfs序 线段树
    dfs序介绍
    poj 3321 dfs序 树状数组 前向星
    cf 1060d 思维贪心
    【PAT甲级】1126 Eulerian Path (25分)
    【PAT甲级】1125 Chain the Ropes (25分)
  • 原文地址:https://www.cnblogs.com/hhhhhhhhhhhhhhhhhhhhhhhhhhh/p/3885605.html
Copyright © 2011-2022 走看看