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; }
  • 相关阅读:
    java数据类型
    索引的种类和优缺点
    IntelliJ IDEA 自动导入快捷键
    KTV点歌系统------LinkedList
    KTV 点歌系统------ArrayList
    超市购物程序
    awk 入门教程
    Git 分支开发规范
    私有镜像仓库Harbor设置https、http访问
    私有镜像仓库Harbor部署
  • 原文地址:https://www.cnblogs.com/sola1994/p/4271240.html
Copyright © 2011-2022 走看看