zoukankan      html  css  js  c++  java
  • POJ 3468 A Simple Problem with Integers(线段树 区间更新)

    http://poj.org/problem?id=3468

    题意 :对于一个序列有两种操作

             1 查询 l到r 的和

             2 对于l 到r上的每个数 加上 up

    思路: 用单点更新必然超时 所以需要区间更新

     (位运算时 注意 m-m>>1 与 m-(m>>1) 的区别)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    __int64 sum[1000000];
    __int64 add[1000000];
    void push(int rt)
    {
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    void pushdown(int rt,int m)
    {
        //if(rt==5) printf("%I64d %d
    ",add[rt],m);
        if(add[rt])
        {
            add[rt<<1]+=add[rt];
            add[rt<<1|1]+=add[rt];
            sum[rt<<1]+=add[rt]*(m-(m>>1));
            sum[rt<<1|1]+=add[rt]*(m>>1);
            //if(rt<<1==10) printf("%I64d %d %d
    ",sum[rt<<1],m,m-m/2);
            add[rt]=0;
        }
    }
    void build(int l,int r,int rt)
    {
        if(l==r)
        {
            scanf("%I64d",&sum[rt]);
            //if(rt==18) printf("%d...
    ",sum[rt]);
            return ;
        }
        int m=(l+r)>>1;
        build(l  ,m,rt<<1);
        build(m+1,r,rt<<1|1);
        push(rt);
    }
    __int64 query(int L,int R,int l,int r,int rt) //query(l,r,1,n,1)
    {
        if(L<=l&&r<=R)
        {
            return sum[rt];
        }
        pushdown(rt,r-l+1);
        int m=(l+r)>>1;
        __int64 ret=0;
        if(L<=m) ret+= query(L,R,l,m,rt<<1);
        if(m<R)  ret+= query(L,R,m+1,r,rt<<1|1);
        return ret;
    }
    void update(int L,int R,int up,int l,int r,int rt)//update(l,r,up,1,n,1);
    {
        if(L<=l&&r<=R)
        {
            add[rt]+=up;
            sum[rt]+=(__int64)up*(r-l+1);
            return ;
        }
        int m=(l+r)>>1;
        pushdown(rt,r-l+1);
        if(L<=m) update(L,R,up,l,m,rt<<1);
        if(m<R)  update(L,R,up,m+1,r,rt<<1|1);
        push(rt);
    }
    int main()
    {
        int n,m;
        int i,j,k;
        int l,r,up;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            build(1,n,1);
            memset(add,0,sizeof(add));
            char que[10];
            while(m--)
            {
                scanf("%s",que);
                if(que[0]=='Q')
                {
                    scanf("%d%d",&l,&r);
                    printf("%I64d
    ",query(l,r,1,n,1));
                }
                else if(que[0]=='C')
                {
                    scanf("%d%d%d",&l,&r,&up);
                    update(l,r,up,1,n,1);
                }
                else if(que[0]=='a')
                {
                    int temp;
                    scanf("%d",&temp);
                    //printf("%I64d I64d
    ",sum[temp],add[temp]);
                }
            }
        }
        return 0;
    }#include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    __int64 sum[1000000];
    __int64 add[1000000];
    void push(int rt)
    {
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    void pushdown(int rt,int m)
    {
        //if(rt==5) printf("%I64d %d
    ",add[rt],m);
        if(add[rt])
        {
            add[rt<<1]+=add[rt];
            add[rt<<1|1]+=add[rt];
            sum[rt<<1]+=add[rt]*(m-(m>>1));    //   m-m>>1 与 m-(m>>1) 的结果完全不同
            sum[rt<<1|1]+=add[rt]*(m>>1);
            //if(rt<<1==10) printf("%I64d %d %d
    ",sum[rt<<1],m,m-m/2);
            add[rt]=0;
        }
    }
    void build(int l,int r,int rt)
    {
        if(l==r)
        {
            scanf("%I64d",&sum[rt]);
            //if(rt==18) printf("%d...
    ",sum[rt]);
            return ;
        }
        int m=(l+r)>>1;
        build(l  ,m,rt<<1);
        build(m+1,r,rt<<1|1);
        push(rt);
    }
    __int64 query(int L,int R,int l,int r,int rt) //query(l,r,1,n,1)
    {
        if(L<=l&&r<=R)
        {
            return sum[rt];
        }
        pushdown(rt,r-l+1);
        int m=(l+r)>>1;
        __int64 ret=0;
        if(L<=m) ret+= query(L,R,l,m,rt<<1);
        if(m<R)  ret+= query(L,R,m+1,r,rt<<1|1);
        return ret;
    }
    void update(int L,int R,int up,int l,int r,int rt)//update(l,r,up,1,n,1);
    {
        if(L<=l&&r<=R)
        {
            add[rt]+=up;
            sum[rt]+=(__int64)up*(r-l+1);
            return ;
        }
        int m=(l+r)>>1;
        pushdown(rt,r-l+1);
        if(L<=m) update(L,R,up,l,m,rt<<1);
        if(m<R)  update(L,R,up,m+1,r,rt<<1|1);
        push(rt);
    }
    int main()
    {
        int n,m;
        int i,j,k;
        int l,r,up;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            build(1,n,1);
            memset(add,0,sizeof(add));
            char que[10];
            while(m--)
            {
                scanf("%s",que);
                if(que[0]=='Q')
                {
                    scanf("%d%d",&l,&r);
                    printf("%I64d
    ",query(l,r,1,n,1));
                }
                else if(que[0]=='C')
                {
                    scanf("%d%d%d",&l,&r,&up);
                    update(l,r,up,1,n,1);
                }
    /*
    else if(que[0]=='a') { int temp; scanf("%d",&temp); }*/ } } return 0; }
  • 相关阅读:
    Object-C,NSSet,不可变集合
    NYIST 860 又见01背包
    NYIST 1070 诡异的电梯【Ⅰ】
    HDU 1542 Atlantis
    HDU 4756 Install Air Conditioning
    CodeForces 362E Petya and Pipes
    HDU 4751 Divide Groups
    HDU 3081 Marriage Match II
    UVA 11404 Palindromic Subsequence
    UVALIVE 4256 Salesmen
  • 原文地址:https://www.cnblogs.com/sola1994/p/4271240.html
Copyright © 2011-2022 走看看