//笑呵呵, 大自然的搬运工。

1、区间求和

 

#include <cstdio>
#define N 1000001
int a[N];
struct node 
{
    int left, right, sum;
}num[3*N];
int build(int left, int right, int cnt)
{ 
    int mid;
    num[cnt].left=left;
    num[cnt].right=right;
    num[cnt].sum=0;
    mid=(left+right)>>1;
    if(left==right)
        return num[cnt].sum=a[left]; 
    else
        return num[cnt].sum=build(left, mid, cnt*2)+build(mid+1, right, cnt*2+1);
}
int query(int left, int right, int cnt)
{
    int mid;
    if(num[cnt].left==left&&num[cnt].right==right)
        return num[cnt].sum;
    mid=(num[cnt].left+num[cnt].right)>>1;
    if(right<=mid)
        return query(left, right, cnt*2);
    else if(left>mid)
        return query(left, right, cnt*2+1);
    else
        return query(left, mid, cnt*2)+query(mid+1, right, cnt*2+1); 
} 
int main()
{
    int n, m, i, begin, end;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        for(int i=1; i<=n; i++)
            scanf("%d", &a[i]);
        build(1, n, 1);
        while(m--)
        {
            scanf("%d%d", &begin, &end);
            printf("%d\n", query(begin, end, 1));
        }
    }
    return 0;
}
         

2、

单点更新+区间求和

 
#include <cstdio>
#define N 1000001
int a[N];
struct node
{
    int left, right, sum;
}num[3*N];
int build(int left, int right, int cnt)
{
    int mid;
    num[cnt].left=left;
    num[cnt].right=right;
    num[cnt].sum=0;
    mid=(left+right)>>1;
    if(left==right)
        return num[cnt].sum=a[left];
    else
        return num[cnt].sum=build(left, mid, cnt*2)+build(mid+1, right, cnt*2+1); 
}
int query(int left, int right, int cnt)
{
    if(num[cnt].left==left&&num[cnt].right==right)
        return num[cnt].sum;
    int mid=(num[cnt].left+num[cnt].right)>>1;
    if(right<=mid)
        return query(left, right, cnt*2);
    else if(left>mid)
        return query(left, right, cnt*2+1);
    else
        return query(left, mid, cnt*2)+query(mid+1, right, cnt*2+1);
}
int add(int pos, int count, int cnt)
{
    int mid;
    num[cnt].sum+=count;
    if(num[cnt].left==num[cnt].right)
        return 0;
    mid=(num[cnt].left+num[cnt].right)>>1;
    if(pos<=mid)  //Notice;
        add(pos, count, cnt*2);
    else
        add(pos, count, cnt*2+1); 
}
int main()
{
    int n, m, i, b, d;
    char s[10];
    while(scanf("%d%d", &n, &m)!= EOF)
    {
        for(int i=1; i<=n; i++)
            scanf("%d", &a[i]);
        build(1, n, 1);
        while(m--)
        {
            scanf("%s%d%d", s, &b, &d);
            if(s[0]=='Q')
                printf("%d\n", query(b, d, 1));
            else
                add(b, d, 1);
        }
    }
    return 0;
}        

3、

区间最值差 

 
#include <cstdio>
#define N 100001
//#define MIN(a, b)(a)<(b)?(a):(b)
//#define MAX(a, b)(a)>(b)?(a):(b) 
const int INF = 0x3f3f3f3f;
int a[N];
struct node
{
    int left, right, max, min;    
}num[N*3];
int Max, Min;
int MAX(int a, int b)
{
    if(a>b)
        return a;
    return b;
}
int MIN(int a, int b)
{
    if(a<b)
        return a;
    return b;
}
void build(int left, int right, int cnt)
{
    int mid;
    num[cnt].left=left;
    num[cnt].right=right;
    mid=(left+right)>>1;
    if(left==right)
    {
        scanf("%d", &num[cnt].max);
        num[cnt].min=num[cnt].max;
        return;
    }
    build(left, mid, cnt*2);
    build(mid+1, right, cnt*2+1);
    num[cnt].max=MAX(num[cnt*2].max, num[cnt*2+1].max);
    num[cnt].min=MIN(num[cnt*2].min, num[cnt*2+1].min);
}
void query(int left, int right, int cnt)
{
    int mid;
    if(num[cnt].left==left&&num[cnt].right==right)
    {
        Max=MAX(Max, num[cnt].max);
        Min=MIN(Min, num[cnt].min);
        return;
    }
    mid=(num[cnt].left+num[cnt].right)>>1;
    if(right<=mid)
        query(left, right, cnt*2);
    else if(left>mid)
        query(left, right, cnt*2+1);
    else
    {
        query(left, mid, cnt*2);
        query(mid+1, right, cnt*2+1); 
    } 
        
}
int main()
{
    int n, m, b, d;
//    char s[10];
    scanf("%d%d", &n, &m);
    build(1, n, 1);
    while(m--)
    {
        scanf("%d%d", &b, &d);
        Max=0;
        Min=INF;
        query(b, d, 1);
        printf("%d\n", Max-Min);
    }
    return 0;
}        

4、

区间更新, 单点查询

 
#include <cstdio>
#define N 1000001
struct node
{
    int l, r, c;
}num[N*3];
void build(int o, int l, int r)
{
    num[o].l=l;
    num[o].r=r;
    num[o].c=0;
    if(l<r)
    {
        int mid=(l+r)>>1;
        build(o<<1, l, mid);
        build(o<<1|1, mid+1, r);
    }

}
void pushDown(int o)
{
    if(num[o].c)
    {
        num[o<<1].c+=num[o].c;
        num[o<<1|1].c+=num[o].c;
        num[o].c=0;
    }
}
void update(int o, int l, int r, int c)
{
    if(num[o].l==l&&num[o].r==r)
    {
        num[o].c+=c;
        return;
    }
    int mid=(num[o].l+num[o].r)>>1;
    if(r<=mid)
        update(o<<1, l, r, c);
    else if(l>mid)
        update(o<<1|1, l, r, c);
    else
    {
        update(o<<1, l, mid, c);
        update(o<<1|1, mid+1, r, c);
    }
}
int query(int o, int id)
{
    if(num[o].l==num[o].r)
        return num[o].c;
    int mid=(num[o].l+num[o].r)>>1;
    int ans=num[o].c;
    if(id<=mid)
        ans+=query(o<<1, id); 
    else
        ans+=query(o<<1|1, id);
    return ans;
    /*if(num[o].l<num[o].r)
    {
        pushDown(o);
        int mid=(num[o].l+num[o].r)>>1;
        if(id<=mid)
            return query(o<<1, id);
        else
            return query(o<<1|1, id);
    }*/
    return num[o].c;
}
int main()
{
    int n, m, a, b, c;
    char op[10];
    scanf("%d%d", &n, &m);
    build(1, 1, m);
    while(n--)
    {
        scanf("%s", op);
        if(op[0]=='A')
        {
            scanf("%d%d%d", &a, &b, &c);
            if(!a)
                a++;
            update(1, a, b, c);
        }    
        else
        {
            scanf("%d", &a);
            printf("%d\n", query(1, a));
        }
    } 
    return 0;    
}         

 

posted on 2016-03-15 18:02  cleverbiger  阅读(170)  评论(0)    收藏  举报