HDU-DuoXiao第二场hdu 6315 Naive Operations 线段树

Posted ckxkexing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-DuoXiao第二场hdu 6315 Naive Operations 线段树相关的知识,希望对你有一定的参考价值。

hdu 6315

题意:对于一个数列a,初始为0,每个a[ i ]对应一个b[i],只有在这个数字上加了b[i]次后,a[i]才会+1。

    有q次操作,一种是个区间加1,一种是查询a的区间和。

思路:线段树,一开始没用lazy,TLE了,然后开始想lazy的标记,这棵线段树的特点是,每个节点维护 :一个区间某个a 要增加1所需个数的最小值,一个区间已加上的mx的最大值标记,还有就是区间和sum。 (自己一开始没有想到mx标记,一度想把lazy传回去。

(思路差一点就多开节点标记。

 

技术分享图片
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <cstdlib>
#include <iterator>
#include <cmath>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <stack>
#pragma comment(linker, "/STACK:102400000,102400000")  //c++
using namespace std;

#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "
";
#define pb push_back
#define pq priority_queue

typedef long long ll;
typedef unsigned long long ull;

typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;

#define fi first
#define se second

#define OKC ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A)  //用来压行
#define REP(i , j , k)  for(int i = j ; i <  k ; ++i)


const ll mos = 0x7FFFFFFF;  //2147483647
const ll nmos = 0x80000000;  //-2147483648
const int inf  = 0x3f3f3f3f;
template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<0||ch>9) f|=(ch==-),ch=getchar();
    while (ch>=0&&ch<=9) x=x*10+ch-0,ch=getchar();
    return x=f?-x:x;
}
// #define _DEBUG;         //*//
#ifdef _DEBUG
freopen("input", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
/*----------------------show time----------------------*/
int n,q;
const int maxn = 100009;
int a[maxn],b[maxn];
int sum[maxn*4];
int lazy[maxn*4];
int mx[maxn*4];
int nd[maxn*4];

void pushup(int rt){
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    nd[rt] = min(nd[rt<<1] , nd[rt<<1|1]);
    mx[rt] = max(mx[rt<<1], mx[rt<<1|1]);
    // lazy[rt] = lazy[rt<<1] + lazy[rt<<1|1];
    // lazy[rt<<1] = lazy[rt<<1|1] = 0;
}

    void pushdown(int rt){
        if(lazy[rt]){
            lazy[rt<<1]+= lazy[rt];
            lazy[rt<<1|1] += lazy[rt];
            mx[rt<<1] +=lazy[rt];
            mx[rt<<1|1] +=lazy[rt];
            lazy[rt] = 0;
        }
    }
    void build(int l,int r,int rt){
        if(l==r){
            nd[rt] = b[l];
            lazy[rt] = mx[rt] = sum[rt] = 0;
            return;
        }
        int mid = (l+r)/2;
        build(l,mid,rt<<1);
        build(mid+1,r,rt<<1|1);
        pushup(rt);
    }

    void update(int l,int r,int rt,int L,int R,int k){
            if(l>=L && r<=R)
            {
                    mx[rt] ++;
                    if(mx[rt] < nd[rt]){
                        lazy[rt]++;
                        return;
                    }
                    if(l==r){
                        sum[rt]++;
                        nd[rt]+=b[l];
                        lazy[rt] = 0;
                        return;
                    }

            }
            int mid = (l+r)/2;
            pushdown(rt);
            if(mid >= L)update(l,mid,rt<<1,L,R,k);
            if(mid<R)update(mid+1,r,rt<<1|1,L,R,k);
            pushup(rt);
       }

        ll query(int l,int r,int rt,int L,int R){
                if(l>=L&&r<=R){
                    return sum[rt];
                }
                int mid = (l+r)/2;
                // pushdown(rt);
                ll ans = 0;
                if(mid >= L)ans += query(l,mid,rt<<1,L,R);
                if(mid < R)ans += query(mid+1,r,rt<<1|1,L,R);
                return ans;
        }
int main(){

        while(~scanf("%d%d", &n, &q)){
                
                for(int i=1; i<=n; i++){
                    scanf("%d", &b[i]);
                }
                char s[20];
                build(1,n,1);
                for(int i=1; i<=q; i++){                    
                    int l,r;
                    scanf("%s%d%d", s, &l, &r);
                    if(s[0]==a){
                        update(1,n,1,l,r,0);
                        // debug(a[5]);
                    }
                    else {
                        ll ans = query(1,n,1,l,r);
                        printf("%lld
",ans);  
                    }
                }
        }

    return 0;
}
HDU 6315

 

以上是关于HDU-DuoXiao第二场hdu 6315 Naive Operations 线段树的主要内容,如果未能解决你的问题,请参考以下文章

2019hdu第二场

第二场 hdu 6052 To my boyfriend

HDU 5301 Buildings(2015多校第二场)

2018 hdu 多校 第二场

HDU6312 Game (多校第二场1004) 简单博弈

HDU6602 Longest Subarray hdu多校第二场 线段树