编程语言
首页 > 编程语言> > 算法训练 操作格子

算法训练 操作格子

作者:互联网

逐步向下递归,找到数组内的结点。输入进叶子结点中,然后返回上一个调用的区间(去更新)

去更新这个区间, 这里主要用到的是线段树。小伙伴想了解具体的方法,可以去看看线段树的内容,谈谈我的想法吧,线段树,其实就是算是二叉排序树的一种(但也不像)因为二叉排序树,并不要求是二叉完全树,而线段树是二叉完全树,并要求以二叉排序树的方法进行,查找,更改。

最后一步一步区间进行分配,最后叶子结点都是数组的结点。非叶子都是a[i]到a[j]的区间。所以有了左边界与有边界的说法。

线段树,等等有时间的时候再细谈,

但毕竟写题是为了提升,所以希望,各位不要只在意题,要去了解,题目里所涉及到的内容。

#include <iostream>
using namespace std;
struct linetree
{
    int l=0;//左边界
    int r=0;//右边界
    long long sum=0;//左右子树的和
    int max=0;//左右子树的最大值(也可以叫区间内的最大值)
};
linetree a[500000];
void upnode (int k)
{
    a[k].max=a[2*k+1].max>a[2*k].max?a[2*k+1].max:a[2*k].max;
    a[k].sum=a[2*k+1].sum+a[2*k].sum;
}
int creat(int n[],int fakel,int faker,int k)
{
    if(fakel==faker)
    {
        a[k].l=fakel;
        a[k].r=faker;
        a[k].sum=n[fakel];
        a[k].max=n[fakel];
        return 0;
    }
    else
    {
        a[k].l=fakel;
        a[k].r=faker;
        int middle=(fakel+faker)/2;
        creat(n,fakel,middle,2*k);
        creat(n,middle+1,faker,2*k+1);
        upnode(k);
    }
}
void change(int x,int y,int k)
{
    if(a[k].l==a[k].r&&a[k].l==x)
    {
        a[k].sum=y;
        a[k].max=y;
    }
    else
    {
        int middle;
        middle=(a[k].l+a[k].r)/2;
        if(x<=middle)
        {
            change(x,y,2*k);
        }
        else
        {
            change(x,y,2*k+1);
        }
        upnode(k);
    }
}
int getsum(int x,int y,int k)
{
    if(a[k].l==x&&a[k].r==y)
    {
        return a[k].sum;
    }
    else
    {
        int middle;
        middle=(a[k].l+a[k].r)/2;
        if(y<=middle)
        {
             return getsum(x,y,2*k);
        }
        else if(x<=middle&&y>middle)
        {
            return getsum(x,middle,2*k)+getsum(middle+1,y,2*k+1);
        }
        else
        {
            return getsum(x,y,2*k+1);
        }
    }
}
int getmax(int x,int y,int k)
{
    if(a[k].l==x&&a[k].r==y)
    {
        return a[k].max;
    }
    else
    {
        int middle;
        middle=(a[k].l+a[k].r)/2;
        if(y<=middle)
        {
            return getmax(x,y,2*k);
        }
        else if(x<=middle&&y>middle)
        {
            return getmax(x,middle,2*k)>getmax(middle+1,y,2*k+1)?getmax(x,middle,2*k):getmax(middle+1,y,2*k+1);
        }
        else
        {
            return getmax(x,y,2*k+1);
        }
    }
}
int main()
{
    int m,n;
    cin>>n>>m;
    int b[n+1];
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
    }
    creat(b,1,n,1);
    int x,y;
    for(int i=1;i<=m;i++)
    {
        int loop;
        cin>>loop;
        if(loop==1)
        {
            cin>>x>>y;
            change(x,y,1);
        }
        if(loop==2)
        {
            cin>>x>>y;
            cout<<getsum(x,y,1)<<endl;
        }
        if(loop==3)
        {
            cin>>x>>y;
            cout<<getmax(x,y,1)<<endl;
        }
    }
    return 0;
}

标签:return,格子,训练,int,max,fakel,middle,算法,getmax
来源: https://blog.csdn.net/qq_56202771/article/details/123635185