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;
}

  




原文地址:https://www.cnblogs.com/Przz/p/5409778.html