M题97.3%通过率求调(可直接看solve()部分)

#include <bits/stdc++.h>
 
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using u128 = unsigned __int128;
using namespace std;
//板子板子板子板子板子板子
// 线段树节点结构体
struct Node {
    i64 sum = 0;    // 区间和
    i64 max_val = LLONG_MIN; // 区间最大值
    i64 min_val = LLONG_MAX; // 区间最小值
    i64 lazy = 0;   // 延迟标记
    i64 left = 0;   // 区间左端点
    i64 right = 0;  // 区间右端点
};

class SegmentTree {
private:
    vector<Node> tree;  // 线段树数组
    vector<i64> data;   // 原始数据

    // 构建线段树
    void build(i64 rt, i64 left, i64 right) {
        tree[rt].left = left;
        tree[rt].right = right;
        tree[rt].lazy = 0;
        if (left == right) {
            tree[rt].sum = data[left];
            tree[rt].max_val = data[left];
            tree[rt].min_val = data[left];
            return;
        }
        i64 mid = (left + right) / 2;
        build(2 * rt, left, mid);         // 递归构建左子树
        build(2 * rt + 1, mid + 1, right); // 递归构建右子树
        tree[rt].sum = tree[2 * rt].sum + tree[2 * rt + 1].sum; // 更新区间和
        tree[rt].max_val = max(tree[2 * rt].max_val, tree[2 * rt + 1].max_val); // 更新区间最大值
        tree[rt].min_val = min(tree[2 * rt].min_val, tree[2 * rt + 1].min_val); // 更新区间最小值
    }

    // 延迟标记下传
    void pushDown(i64 rt) {
        if (tree[rt].lazy != 0) {
            i64 lson = 2 * rt;
            i64 rson = 2 * rt + 1;
            i64 mid = (tree[rt].left + tree[rt].right) / 2;

            // 更新左子节点
            tree[lson].sum += tree[rt].lazy * (mid - tree[rt].left + 1);
            tree[lson].max_val += tree[rt].lazy;
            tree[lson].min_val += tree[rt].lazy;
            tree[lson].lazy += tree[rt].lazy;

            // 更新右子节点
            tree[rson].sum += tree[rt].lazy * (tree[rt].right - mid);
            tree[rson].max_val += tree[rt].lazy;
            tree[rson].min_val += tree[rt].lazy;
            tree[rson].lazy += tree[rt].lazy;

            tree[rt].lazy = 0; // 清空当前节点的延迟标记
        }
    }

public:
    // 构造函数,初始化线段树
    SegmentTree(const vector<i64>& input) : data(input) {
        i64 n = data.size() - 1; // 数据从下标1开始
        tree.resize(4 * n + 1);  // 线段树大小为4倍数据大小
        build(1, 1, n);          // 从根节点开始构建
    }

    // 区间更新:将区间 [ul, ur] 内的每个数加上 k
    void updateRange(i64 rt, i64 ul, i64 ur, i64 k) {
        i64 left = tree[rt].left;
        i64 right = tree[rt].right;
        if (ur < left || ul > right) {
            return; // 当前区间与更新区间无交集
        }
        if (ul <= left && ur >= right) {
            // 当前区间完全包含在更新区间内
            tree[rt].sum += k * (right - left + 1);
            tree[rt].max_val += k;
            tree[rt].min_val += k;
            tree[rt].lazy += k;
            return;
        }
        pushDown(rt); // 下传延迟标记
        updateRange(2 * rt, ul, ur, k);     // 更新左子树
        updateRange(2 * rt + 1, ul, ur, k); // 更新右子树
        tree[rt].sum = tree[2 * rt].sum + tree[2 * rt + 1].sum; // 更新当前节点
        tree[rt].max_val = max(tree[2 * rt].max_val, tree[2 * rt + 1].max_val); // 更新区间最大值
        tree[rt].min_val = min(tree[2 * rt].min_val, tree[2 * rt + 1].min_val); // 更新区间最小值
    }

    // 区间查询:查询区间 [ql, qr] 的和
    i64 querySum(i64 rt, i64 ql, i64 qr) {
        i64 left = tree[rt].left;
        i64 right = tree[rt].right;
        if (qr < left || ql > right) {
            return 0; // 当前区间与查询区间无交集
        }
        if (ql <= left && qr >= right) {
            return tree[rt].sum; // 当前区间完全包含在查询区间内
        }
        pushDown(rt); // 下传延迟标记
        return querySum(2 * rt, ql, qr) + querySum(2 * rt + 1, ql, qr); // 返回左右子树的查询结果
    }

    // 区间查询:查询区间 [ql, qr] 的最大值
    i64 queryMax(i64 rt, i64 ql, i64 qr) {
        i64 left = tree[rt].left;
        i64 right = tree[rt].right;
        if (qr < left || ql > right) {
            return LLONG_MIN; // 当前区间与查询区间无交集
        }
        if (ql <= left && qr >= right) {
            return tree[rt].max_val; // 当前区间完全包含在查询区间内
        }
        pushDown(rt); // 下传延迟标记
        return max(queryMax(2 * rt, ql, qr), queryMax(2 * rt + 1, ql, qr)); // 返回左右子树的最大值
    }

    // 区间查询:查询区间 [ql, qr] 的最小值
    i64 queryMin(i64 rt, i64 ql, i64 qr) {
        i64 left = tree[rt].left;
        i64 right = tree[rt].right;
        if (qr < left || ql > right) {
            return LLONG_MAX; // 当前区间与查询区间无交集
        }
        if (ql <= left && qr >= right) {
            return tree[rt].min_val; // 当前区间完全包含在查询区间内
        }
        pushDown(rt); // 下传延迟标记
        return min(queryMin(2 * rt, ql, qr), queryMin(2 * rt + 1, ql, qr)); // 返回左右子树的最小值
    }
};
struct arry{
    i64 nums;
    i64 xuhao;
};
bool com(arry x,arry y){
    return x.nums<y.nums;
}
void solve() {
    // 示例数据
    i64 n;
    cin>>n;
    vector<i64> data (n+1,0); // 数据从下标1开始
    for(int i = 1; i<= n ; i++){
        cin>>data[i];
    }
    SegmentTree st(data);
    vector <arry> nums(n+1);
    for (int i = 1; i <=n; ++i)
    {
        nums[i].nums=data[i];
        nums[i].xuhao=i;
    }
    sort(nums.begin()+1,nums.end(),com);
    vector <i64 > minnums;

    i64 l=nums[1].xuhao;
    i64 r=nums[1].xuhao;
    i64 i=1;
    while(r!=n)
    {

        i64 tree_max_num=st.queryMax(1,l,r)*2;
        i64 tree_min_num=st.queryMin(1,l,r)*2;
        i64 whole_max_num=max(st.queryMax(1,1,l-1),st.queryMax(1,r+1,n));
        i64 whole_min_num=min(st.queryMin(1,1,l-1),st.queryMin(1,r+1,n));
        minnums.push_back(max(max(tree_max_num,whole_max_num),max(tree_min_num,whole_min_num))-min(min(tree_min_num,whole_min_num),min(tree_max_num,whole_max_num)));
        
        l=min(l,nums[i+1].xuhao);
        r=max(r,nums[i+1].xuhao);
        i+=1;
    }
    minnums.push_back(2*(st.queryMax(1,1,n)-st.queryMin(1,1,n)));
    sort(minnums.begin(),minnums.end());

    cout<<minnums[0]<<endl;
    // 操作1:区间更新,将区间 [2, 4] 内的每个数加上 2
    //st.updateRange(1, 2, 4, 2);

    // 操作2:区间查询,查询区间 [2, 4] 的和
    //cout << "Sum of [2, 4]: " << st.querySum(1, 2, 4) << endl; // 输出:11

    // 操作3:区间查询,查询区间 [2, 4] 的最大值
    //cout << "Max of [2, 4]: " << st.queryMax(1, 2, 4) << endl; // 输出:6

    // 操作4:区间查询,查询区间 [2, 4] 的最小值
    //cout << "Min of [2, 4]: " << st.queryMin(1, 2, 4) << endl; // 输出:4

    // 操作5:区间更新,将区间 [1, 5] 内的每个数加上 1
    //st.updateRange(1, 1, 5, 1);

    // 操作6:区间查询,查询区间 [1, 4] 的和
    //cout << "Sum of [1, 4]: " << st.querySum(1, 1, 4) << endl; // 输出:20

    // 操作7:区间查询,查询区间 [1, 4] 的最大值
    //cout << "Max of [1, 4]: " << st.queryMax(1, 1, 4) << endl; // 输出:7

    // 操作8:区间查询,查询区间 [1, 4] 的最小值
    //cout << "Min of [1, 4]: " << st.queryMin(1, 1, 4) << endl; // 输出:3

    return ;
}



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
     
    int t=1;
    //cin >> t;
     
    while (t--) {
        solve();
    }
     
    return 0;
}

全部评论

相关推荐

AAA专业长城贴瓷砖刘大爷:这样的简历我会直接丢进垃圾桶,花里胡哨的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务