zoukankan      html  css  js  c++  java
  • ACwing 245. 你能回答这些问题吗(线段树区间子段最大值+单点修改)

    给定长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:

    1、“1 x y”,查询区间 [x,y] 中的最大连续子段和,即 maxxlrymaxx≤l≤r≤y{ri=lA[i]∑i=lrA[i]}。

    2、“2 x y”,把 A[x] 改成 y。

    对于每个查询指令,输出一个整数表示答案。

    输入格式

    第一行两个整数N,M。

    第二行N个整数A[i]。

    接下来M行每行3个整数k,x,y,k=1表示查询(此时如果x>y,请交换x,y),k=2表示修改。

    输出格式

    对于每个查询指令输出一个整数表示答案。

    每个答案占一行。

    数据范围

    N500000,M100000N≤500000,M≤100000

    输入样例:

    5 3
    1 2 -3 4 5
    1 2 3
    2 2 -1
    1 3 2
    

    输出样例:

    2
    -1
    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define eps 1e-9
    
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int maxn = 500000 + 8;
    
    int n, m, k, x, y;
    ll a[maxn];
    
    struct node
    {
        int l, r;
        ll sum, dat, lmax, rmax;
    }tree[4 * maxn];
    
    void push_down(int i)
    {
        tree[i].sum = tree[i * 2].sum + tree[i * 2 + 1].sum;
        tree[i].lmax = max(tree[i * 2].lmax, tree[i * 2].sum + tree[i * 2 + 1].lmax);///紧靠左端的最大连续子段和
        tree[i].rmax = max(tree[i * 2 + 1].rmax, tree[i * 2 + 1].sum + tree[i * 2].rmax);///紧靠右端的最大连续子段和
        tree[i].dat = max(tree[i * 2].dat, max(tree[i * 2 + 1].dat, tree[i * 2].rmax + tree[i * 2 + 1].lmax));///区间连续最大字段和
    }
    
    void build(int i, int l, int r)
    {
        tree[i].l = l;
        tree[i].r = r;
        if(l == r)
        {
            tree[i].sum = a[l];
            tree[i].dat = a[l];
            tree[i].lmax = a[l];
            tree[i].rmax = a[l];
            return;
        }
        int mid = (l + r) / 2;
        build(i * 2, l, mid);
        build(i * 2 + 1, mid + 1, r);
        push_down(i);
    }
    
    void change(int i, int pos, int k)
    {
        if(tree[i].l == tree[i].r)
        {
            tree[i].sum = k;
            tree[i].sum = k;
            tree[i].dat = k;
            tree[i].lmax = k;
            tree[i].rmax = k;
            return;
        }
        int mid = (tree[i].l + tree[i].r) / 2;
        if(pos <= mid)
            change(i * 2, pos, k);
        else
            change(i * 2 + 1, pos, k);
        push_down(i);
    }
    
    node tmp;
    
    node search(int i, int l, int r)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            return tree[i];
        }
        node a, b, c;
        a.dat = a.lmax = a.rmax = a.sum = -inf;///左儿子
        b.dat = b.lmax = b.rmax = b.sum = -inf;///右儿子
        c.dat = c.lmax = c.rmax = -inf;///父节点
        c.sum = 0;
        int mid = (tree[i].l + tree[i].r) / 2;
        if(l <= mid && r <= mid)
        {
            a = search(i * 2, l, r);
            c.sum += a.sum;
        }
        else if(mid < r && mid < l)
        {
            b = search(i * 2 + 1, l, r);
            c.sum += b.sum;
        }
        else
        {
            a = search(i * 2, l, r);
            b = search(i * 2 + 1, l, r);
            c.sum += a.sum + b.sum;
        }
        c.dat = max(c.dat, max(a.rmax + b.lmax, max(a.dat, b.dat)));///区间连续最大字段和
        c.lmax = max(c.lmax, max(a.lmax, a.sum + b.lmax));///紧靠左端的最大连续子段和
        c.rmax = max(c.rmax, max(b.rmax, b.sum + a.rmax));///紧靠右端的最大连续子段和
        return c;
    }
    
    int main()
    {
        std::ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        cin>>n>>m;
        for(int i = 1; i <= n; i++)
            cin>>a[i];
        build(1, 1, n);
        for(int i = 0; i < m; i++)
        {
            cin>>k>>x>>y;
            if(k == 1)
            {
                if(x > y)
                    swap(x, y);
                cout<<search(1, x, y).dat<<'
    ';
            }
            else if(k == 2)
            {
                a[x] = y;
                change(1, x, y);
            }
        }
        return 0;
    }

  • 相关阅读:
    Java实现各种内部排序算法
    Java实现堆排序(大根堆)
    Java对象的序列化和反序列化
    Java实现链式存储的二叉查找树(递归方法)
    337. House Robber III(包含I和II)
    318. Maximum Product of Word Lengths
    114. Flatten Binary Tree to Linked List
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    96. Unique Binary Search Trees(I 和 II)
  • 原文地址:https://www.cnblogs.com/RootVount/p/11432182.html
Copyright © 2011-2022 走看看