zoukankan      html  css  js  c++  java
  • HDU 6315

    题意略。

    思路:本题的思路总的来说就是暴力 + 剪枝。

    我们依然用线段树来维护:

    定义结点node{ l , r , minn , contirbute} 分别为某个区间的左右端点,和该区间(b序列)内的最小值与该区间对答案的贡献。

    当我们修改到某一个区间的时候,如果该区间的minn > 1,那么minn--,并且给该区间打上懒标记。

    如果该区间的minn == 1,那么我们看一下这个区间的左右两个子区间,对于minn > 1的子区间,我们就采取上面的操作。

    对于minn == 1的子区间,我们就一直往下找,直到定位到了最底层的叶子节点,对于该子节点的minn,我们将它复原,但是把它的contribute += 1。

    其实就是利用minn值来剪枝。

    详见代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 5;
    
    struct node{
        int l,r,minn,contri;
        node(int a = 0,int b = 0,int c = 0,int d = 0){
            l = a,r = b,minn = c,contri = d;
        }
    };
    
    node store[maxn<<2];
    int depot[maxn],add[maxn<<2],n,q;
    char op[10];
    
    void pushup(int id){
        store[id].contri = store[id<<1].contri + store[id<<1 | 1].contri;
        store[id].minn = min(store[id<<1].minn,store[id<<1 | 1].minn);
    }
    void pushdown(int id){
        if(add[id]){
            store[id<<1].minn -= add[id];
            store[id<<1 | 1].minn -= add[id];
            add[id<<1] += add[id];
            add[id<<1 | 1] += add[id];
            add[id] = 0;
        }
    }
    void build(int l,int r,int id){
        store[id].l = l,store[id].r = r;
        if(l == r){
            store[id].minn = depot[l];
            store[id].contri = 0;
            return;
        }
        int mid = (l + r)>>1;
        build(l,mid,id<<1);
        build(mid + 1,r,id<<1 | 1);
        pushup(id);
    }
    void modify(int l,int r,int id){
        
        if(store[id].l == l && store[id].r == r && store[id].minn > 1){
            store[id].minn -= 1;
            add[id] += 1;
            return;
        }
        if(store[id].l == store[id].r){
            store[id].minn -= 1;
            add[id] += 1;
            if(store[id].minn <= 0){
                store[id].minn = depot[l];
                store[id].contri += 1;
            }
            return;
        }
        pushdown(id);
        int mid = (store[id].l + store[id].r)>>1;
        if(r <= mid) modify(l,r,id<<1);
        else if(mid < l) modify(l,r,id<<1 | 1);
        else{
            modify(l,mid,id<<1);
            modify(mid + 1,r,id<<1 | 1);
        }
        pushup(id);
    }
    int query(int l,int r,int id){
        if(store[id].l == l && store[id].r == r){
            return store[id].contri;
        }
        pushdown(id);
        int mid = (store[id].l + store[id].r)>>1;
        int ret = 0;
        if(r <= mid) ret = query(l,r,id<<1);
        else if(mid < l) ret = query(l,r,id<<1 | 1);
        else ret = query(l,mid,id<<1) + query(mid + 1,r,id<<1 | 1);
        pushup(id);
        return ret;
    }
    
    int main(){
        while(scanf("%d%d",&n,&q) == 2){
            memset(add,0,sizeof(add));
            for(int i = 1;i <= n;++i){
                scanf("%d",&depot[i]);
            }
            build(1,n,1);
            for(int i = 0;i < q;++i){
                int l,r;
                scanf("%s%d%d",op,&l,&r);
                if(op[0] == 'a'){
                    modify(l,r,1);
                }
                else{
                    int ans = query(l,r,1);
                    printf("%d
    ",ans);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    商业智能添加维度智能简介
    1049 数列的片段和 (20 分)
    1045 快速排序 (25 分)
    1044 火星数字 (20 分)
    1136 A Delayed Palindrome (20 分)
    1128 N Queens Puzzle (20 分)
    1124 Raffle for Weibo Followers (20 分)
    1125 Chain the Ropes (25 分)
    1121 Damn Single (25 分)
    1116 Come on! Let's C (20 分)
  • 原文地址:https://www.cnblogs.com/tiberius/p/9369683.html
Copyright © 2011-2022 走看看