zoukankan      html  css  js  c++  java
  • 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;
    }
    

      




  • 相关阅读:
    LeetCode 1122. Relative Sort Array (数组的相对排序)
    LeetCode 46. Permutations (全排列)
    LeetCode 47. Permutations II (全排列 II)
    LeetCode 77. Combinations (组合)
    LeetCode 1005. Maximize Sum Of Array After K Negations (K 次取反后最大化的数组和)
    LeetCode 922. Sort Array By Parity II (按奇偶排序数组 II)
    LeetCode 1219. Path with Maximum Gold (黄金矿工)
    LeetCode 1029. Two City Scheduling (两地调度)
    LeetCode 392. Is Subsequence (判断子序列)
    写程序判断系统是大端序还是小端序
  • 原文地址:https://www.cnblogs.com/Przz/p/5409778.html
Copyright © 2011-2022 走看看