官方题解——最简单的一道题

最简单的一道题

http://www.nowcoder.com/questionTerminal/d62a5ac2f83643cc83ee633e33a0073b

D - 最简单的一道题

​解法是线段树,定义 为区间 满足( ,且对于位置 ,位置 到位置 的这段区间的最小值是位置 的值)的 的数目,每个区间保存区间最小值和 。询问时设一个当前值 ,初始为询问的值,当前区间左边界小于所求位置时,继续递归,大于所求位置时,判断区间最小值是否小于 ,是的话加左子区间继续递归,右子区间不搜索,直接加上 ,更新 。或者区间长度为 且当前值小于 ,答案 并返回。

这个是出题人给的题解,我暴力验证了一下,结果数据放错了,继续背锅。。。
我自己懒得写,有时间写一下吧,先放出题人的代码。

#include<iostream>
#include<bits/stdc++.h>
#include<time.h>
using namespace std;

#define lson (p<<1)
#define rson ( (p<<1) |1)
#define mid ((l+r)>>1)

#define MAX 200005
struct node{
    node(){
        minn = value = add = 0;
    }
    void init(){
        minn = value = add = 0;
    }
    int minn;
    int value;
    int add;
};

struct Segt{
    int arr[MAX];
    node tree[MAX<<2];
    void push_down(int p){
        if(tree[p].add != 0){
            tree[lson].add += tree[p].add;
            tree[rson].add += tree[p].add;
            tree[lson].minn += tree[p].add;
            tree[rson].minn += tree[p].add;
            tree[p].add = 0;
        }

    }

    void push_up(int l, int r, int p){
        //bool flag = true;
        tree[p].minn = min(tree[lson].minn,tree[rson].minn);
        int m = mid;
        int val = tree[lson].minn;
        tree[p].value = que(m+1,val,m+1,r,rson);
    }

    void build(int l, int r, int p){
        tree[p].init();
        if(l == r){
            tree[p].minn = arr[l];
            tree[p].value = 0;
            return;
        }
        int m = mid;
        build(l,m,lson); build(m+1,r,rson);
        push_up(l,r,p);
    }
    void update(int a, int b, int k, int l, int r, int p){
            if(l >= a && r <= b){
                tree[p].minn += k;
                tree[p].add += k;
                return;
            }
            push_down(p);
            int m = mid;
            if(a <= m) update(a,b,k,l,m,lson);
            if(b > m) update(a,b,k,m+1,r,rson);
            push_up(l,r,p);
    }
    int get_val(int pos,int l, int r, int p){
        if(l == r) return tree[p].minn;
        push_down(p);
        int m = mid;
        if(pos <= m) return get_val(pos,l,m,lson);
        else return get_val(pos,m+1,r,rson);
       // push_up(p);
    }
    int que(int a, int& val, int l, int r, int p){
        if(a > r) return 0;
        int m = mid;
     //   cout << l << ' ' << r << endl;
        if(l != r) push_down(p);
        if(l >= a){
            if(tree[p].minn <= val){
                if(l == r){
                 //   cout << "#" << val << ' ' <<  l << ' ' << tree[p].minn << endl;
                    val = tree[p].minn;
                    return 1;
                }
                if(tree[lson].minn <= val){
                    int an = que(a,val,l,m,lson);
                    val = tree[p].minn;
                  //  cout << "@" << val << ' ' << l << ' ' << r << ' ' << an << ' ' << tree[p].value << endl;
                    return an + tree[p].value;
                }else{
                    return que(a,val,m+1,r,rson);
                }
            }else{
                return 0;
            }
        }
        if(a <= m){
            int an = que(a,val,l,m,lson);
            if(val == tree[lson].minn){
                 val = tree[p].minn;
                 return an + tree[p].value;
            }else{
                return an + que(a,val,m+1,r,rson);
            }
        }else{
            return que(a,val,m+1,r,rson);
        }
    }



};
Segt segt;

void make_input(ostream & out){
    srand(time(NULL));
    int limit1 = 200000;
    int limitk = 10000;
    int n = rand()%limit1 + 5;
    int m = rand()%limit1 + 5;
    out << n << ' ' << m << endl;
    for(int i = 1; i <= n; i++){
        out << rand()%limitk << ' ';
    }
    out << endl;
    for(int i = 1; i <= m; i++){
        int f = rand()%2;
        if(f){
            int l = 1 + rand() %(n-1);
            int r = l + rand() %(n - l);
            int k = rand() % limitk;
            out << "c " << l << ' ' << r << ' ' << k << endl;
        }else{
            int x = 1 + rand() %(n-1);
            out << "q " << x << endl;
        }
    }
}
/*
5 5
1 2 3 4 3
q 3
c 1 3 3
q 2
c 5 5 4
q 5

*/
void make_ans(istream & in, ostream & out){
    int n, m;
    in >> n >> m;
    for(int i = 1; i <= n; i++){
        in >> segt.arr[i];
    }
    segt.build(1,n,1);
    while(m--){
        char ch;
      /*  cout << "------" << endl;
        for(int i = 1; i <= n; i++) cout << segt.get_val(i,1,n,1) << ' '; cout << endl;
        cout << "------" << endl;*/
        in >> ch;
        if(ch == 'c'){
            int l, r, k;
            in >> l >> r >> k;
            segt.update(l,r,k,1,n,1);
        }else{
            int x;
            in >> x;
            int val = segt.get_val(x,1,n,1);
          //  cout << val << endl;
            out << segt.que(x+1,val,1,n,1) << endl;
        }
    }
}

int main(void){
    make_ans(cin,cout);
    return 0;
}
全部评论

相关推荐

肥沃富饶:可能初创公司,老板不懂技术
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
02-14 11:10
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务