• poj 3264 & poj 3468(线段树)


    poj 3264

    Sample Input

    6 3
    1
    7
    3
    4
    2
    5
    1 5
    4 6
    2 2

    Sample Output

    6
    3
    0

    求任一区间的最大值和最小值的差

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    #define N 50005
    #define mod 258280327
    #define MIN 0
    #define MAX 1000001
    struct node
    {
        int val,maxn,minx;
        int Left,Right;
    } pnode[4*N];
    int a[N];
    int tmax,tmin;
    void build(int i,int l,int r)
    {
        pnode[i].Left = l;
        pnode[i].Right = r;
        pnode[i].maxn = MIN;
        pnode[i].minx = MAX;
        if(l == r)
            return;
        build(i*2,l ,(l+r)/2);
        build(i*2+1, (l+r)/2 + 1,r);
    }
    
    void insert(int i,int index,int va)
    {
        if(pnode[index].Left == pnode[index].Right)
        {
            pnode[index].maxn = pnode[index].minx = va;
            return ;
        }
        pnode[index].maxn = max(pnode[index].maxn,va);
        pnode[index].minx = min(pnode[index].minx,va);
        int mid = (pnode[index].Left+pnode[index].Right)/2;
        if (mid >= i)
            insert(i,index*2,va);
        else
            insert(i,index*2+1, va);
    }
    
    void query(int u,int l,int r,int a,int b)
    {
    //    if(pnode[u].minx >= tmin &&  pnode[u].maxn < tmax)
    //        return;
        if(a == l && b == r)
        {
            if(tmax < pnode[u].maxn)
                tmax = pnode[u].maxn;
            if(tmin > pnode[u].minx)
                tmin = pnode[u].minx;
            return ;
        }
    
        int mid = (l + r)>>1;
        if (mid >= b)
            query(u*2,l, mid,  a, b);
        else if (mid < a)
            query(u*2+1,mid+1, r,  a, b);
        else
        {
            query(u*2,l, mid,  a, mid);
            query( u*2+1,mid+1, r, mid+1, b);
        }
    }
    
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        build(1,1,n);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d",&a[i]);
            insert(i,1,a[i]);
        }
    
        for(int i = 1; i <= m; i++)
        {
            int x,y;
            tmax = -MAX;
            tmin = MAX;
            scanf("%d%d",&x,&y);
            query(1,1,n,x,y);
            printf("%d
    ",tmax-tmin);
        }
    
        return 0;
    }
    

      



    poj 3468


    Sample Input

    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 4 4
    Q 1 10
    Q 2 4
    C 3 6 3
    Q 2 4
    

    Sample Output

    4
    55
    9
    15


    ①对区间i - j 的数全加上c ;   ②求区间的和


    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    #define N 100005
    #define mod 258280327
    #define MIN 0
    #define MAX 1000001
    
    struct node
    {
        ll val,els;
        int Left,Right;
    } pnode[4*N];
    
    int a[N];
    int tmax,tmin;
    void build(int i,int l,int r)
    {
        pnode[i].Left = l;
        pnode[i].Right = r;
        pnode[i].val = 0;
        pnode[i].els = 0;
        if(l == r)
            return;
        build(i*2,l ,(l+r)/2);
        build(i*2+1, (l+r)/2 + 1,r);
    }
    
    void insert(int i,int index,int va)
    {
        if(pnode[index].Left == pnode[index].Right)
        {
            pnode[index].val = va;
            return ;
        }
        pnode[index].val+=va;
        int mid = (pnode[index].Left+pnode[index].Right)/2;
        if (mid >= i)
            insert(i,index*2,va);
        else
            insert(i,index*2+1, va);
    }
    
    void add(int u,int l,int r,ll c,int a,int b)
    {
        if(a == l && b == r)
        {
            pnode[u].els += c;
            return ;
        }
        pnode[u].val += (b-a+1)*c;       //让大于a,b的部分加上
        if(l == r)
            return ;
        int mid = (l + r)>>1;
        if (mid >= b)
            add(u*2,l, mid, c, a, b);
        else if (mid < a)
            add(u*2+1,mid+1, r, c, a, b);
        else
        {
            add(u*2,l, mid , c,a, mid);
            add(u*2+1,mid+1, r,c, mid+1, b);
        }
    }
    
    long long query(int u,int l,int r,int a,int b)
    {
        if(a == l && b == r)
        {
            return pnode[u].val + (pnode[u].Right - pnode[u].Left + 1)*pnode[u].els;
        }
        pnode[u].val += (pnode[u].Right - pnode[u].Left + 1)*pnode[u].els;
        //当取了a,b的附加值后,将其附加值往下放
        add(u*2,pnode[u].Left,(pnode[u].Left + pnode[u].Right)/2,pnode[u].els,pnode[u].Left,(pnode[u].Left + pnode[u].Right)/2);
        add(u*2+1,(pnode[u].Left+pnode[u].Right)/2+1,pnode[u].Right,pnode[u].els,(pnode[u].Left+pnode[u].Right)/2+1,pnode[u].Right);
        pnode[u].els = 0;
        int mid = (l + r)>>1;
        if (mid >= b)
           return query(u*2,l, mid,  a, b);
        else if (mid < a)
           return query(u*2+1,mid+1, r,  a, b);
        else
        {
           return query(u*2,l, mid,  a, mid)+query( u*2+1,mid+1, r, mid+1, b);
        }
    }
    
    int main()
    {
        int n,m,l,r,c;
        char ch;
        while(scanf("%d%d",&n,&m)!= EOF)
        {
            build(1,1,n);
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&a[i]);
                insert(i,1,a[i]);
            }
    
            for(int i = 1; i <= m; i++)
            {
                getchar();
                ch = getchar();
                if(ch == 'Q')
                {
                    scanf("%d%d",&l,&r);
                    printf("%I64d
    ",query(1,1,n,l,r));
                }
                if(ch == 'C')
                {
                    scanf("%d%d%d",&l,&r,&c);
                    add(1,1,n,c,l,r);
                }
            }
        }
        return 0;
    }
    

      




  • 相关阅读:
    一次郁闷的项目部署经历
    一道面试题的求解
    一次惨痛的教训
    小地方,大郁闷001
    WPF相对资源的访问
    VS2008安装时提示磁盘空间不够的解决办法
    WPFSlider 控件的使用
    关于asp.net大文件上传和进度条实现的学习(1)
    DataList的一次分页困惑
    关于android的XML的解析
  • 原文地址:https://www.cnblogs.com/Przz/p/5409778.html
Copyright © 2020-2023  润新知