• [CF1473D] Program


    [CF1473D] Program - 线段树

    Description

    有一个变量 x 初始为 0,我们按字符串顺序进行“+1”或“-1”操作。有 m 个询问,每次询问我们删去字符串的 l 到 r 的符号后,x 在完成所有操作中出现的不同数值的总数。

    Solution

    线段树每个结点维护 sum 表示这一段的操作和,maxsum 表示执行这一段操作过程中到达的最大值,minsum 表示执行这一段操作过程中到达的最小值。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    struct SegmentTree
    {
        struct Node
        {
            int sum;
            int min_sum;
            int max_sum;
    
            Node()
            {
                sum = 0;
                min_sum = 0;
                max_sum = 0;
            }
    
            Node(int sum, int min_sum, int max_sum) : sum(sum), min_sum(min_sum), max_sum(max_sum)
            {
            }
    
            Node operator+(const Node &rhs)
            {
                return {sum + rhs.sum,
                        min(0ll, min(min_sum, sum + rhs.min_sum)),
                        max(0ll, max(max_sum, sum + rhs.max_sum))};
            }
        };
    
        vector<Node> node;
        int n;
    
        SegmentTree(int n) : n(n)
        {
            node.resize(n * 4 + 2);
        }
    
        void build(int p, int l, int r, const string &str)
        {
            if (l == r)
                node[p] = {str[l - 1] == '+' ? 1 : -1,
                           str[l - 1] == '+' ? 1 : -1,
                           str[l - 1] == '+' ? 1 : -1};
            else
            {
                build(p * 2, l, (l + r) / 2, str);
                build(p * 2 + 1, (l + r) / 2 + 1, r, str);
                node[p] = node[p * 2] + node[p * 2 + 1];
            }
        }
    
        void Build(const string &str)
        {
            build(1, 1, n, str);
        }
    
        Node query(int p, int l, int r, int ql, int qr)
        {
            if (l > qr || r < ql)
                return {0, 0, 0};
            if (l >= ql && r <= qr)
                return node[p];
            return query(p * 2, l, (l + r) / 2, ql, qr) + query(p * 2 + 1, (l + r) / 2 + 1, r, ql, qr);
        }
    
        Node Query(int ql, int qr)
        {
            return query(1, 1, n, ql, qr);
        }
    
        int Solve(int l, int r)
        {
            if (l == 1 && r == n)
                return 1;
            Node t = Query(1, l - 1) + Query(r + 1, n);
            // cout << "solve " << t.sum << " " << t.max_sum << " " << t.min_sum << endl;
            return t.max_sum - t.min_sum + 1;
        }
    };
    
    void solve()
    {
        int n, m;
        cin >> n >> m;
    
        string str;
        cin >> str;
    
        SegmentTree seg(n);
        seg.Build(str);
    
        for (int i = 1; i <= m; i++)
        {
            int l, r;
            cin >> l >> r;
            cout << seg.Solve(l, r) << endl;
        }
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        int t;
        cin >> t;
    
        while (t--)
        {
            solve();
        }
    }
    
  • 相关阅读:
    Docker入门
    服务配置中心
    zuul网关
    git2
    git1
    git
    shiro授权、注解式开发
    shiro认证-SSM
    Shiro入门
    Springmvc之文件上传
  • 原文地址:https://www.cnblogs.com/mollnn/p/14340769.html
Copyright © 2020-2023  润新知