• poj Asimple Problem With Integers 夜


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

    题目大意:

    给你n个整数,两种操作,

    求一段区间的和 

    一段区间内全部加上某个整数

    简单线段树题

    区间内一部分是固定区间和

    另一个是此区间内每个数都需要加的量

    注意用64为整数

    详情见代码注释:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int N=100005;
    struct node
    {
        int l,r;
        long long add;//非固定,需要向下传递的量
        long long v;//固定住的和
    }mem[N*4];
    int a[N];
    long long ans;
    void build(int x,int l,int r)
    {
        mem[x].l=l;
        mem[x].r=r;
        mem[x].add=0;//初始化
        if(l==r)
        {
            mem[x].v=a[l];
        }
        else
        {
            int mid=(l+r)>>1;
            build(x*2,l,mid);
            build(x*2+1,mid+1,r);
            mem[x].v=mem[x*2].v+mem[x*2+1].v;
        }
    }
    void findsum(int x,int i,int j)
    {
        if(mem[x].l==i&&mem[x].r==j)
        {
            ans=ans+mem[x].v+(mem[x].r-mem[x].l+1)*mem[x].add;//如果正好是这个区间
        }
        else
        {
            int mid=(mem[x].l+mem[x].r)>>1;
            mem[x].v+=(mem[x].r-mem[x].l+1)*mem[x].add;//否则向下传递,首先本区间固定量增加
            mem[x*2].add+=mem[x].add;mem[x*2+1].add+=mem[x].add;//然后传给左右区间
            mem[x].add=0;//最后清零
            if(j<=mid)
            {
                findsum(x*2,i,j);
            }else if(i>mid)
            {
                findsum(x*2+1,i,j);
            }else
            {
                findsum(x*2,i,mid);
                findsum(x*2+1,mid+1,j);
            }
        }
    }
    void Addint(int x,int i,int j,int k)
    {
        if(mem[x].l==i&&mem[x].r==j)
        {
            mem[x].add+=k;//本区间改变增加量
        }
        else
        {
            mem[x].v+=(j-i+1)*k;//向下的话,首先本区间先将固定量增加
            int mid=(mem[x].l+mem[x].r)>>1;
            if(j<=mid)
            {
                Addint(x*2,i,j,k);
            }else if(i>mid)
            {
                Addint(x*2+1,i,j,k);
            }else
            {
                Addint(x*2,i,mid,k);
                Addint(x*2+1,mid+1,j,k);
            }
        }
    }
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(int i=1;i<=n;++i)
            {
                scanf("%d",&a[i]);
            }
            build(1,1,n);
            while(m--)
            {
                char c;
                int i,j,k;
                getchar();//吃换行
                scanf("%c",&c);
                if(c=='Q')
                {
                    scanf("%d %d",&i,&j);
                    ans=0;
                    findsum(1,i,j);
                    printf("%I64d\n",ans);
                }
                else
                {
                    scanf("%d %d %d",&i,&j,&k);
                    Addint(1,i,j,k);
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    Android控件显示和隐藏
    Android Viewpager+Fragment实现滑动标签页
    Android中的color使用
    Android自定义Button按钮显示样式
    Android通过Intent传递对象
    Android中AsyncTask的使用
    iOS,推送通知
    UIWebView与JS的交互
    iOS蓝牙中的进制转换,数据格式转换
    Core Graphics 定制UIVIew 处理图片
  • 原文地址:https://www.cnblogs.com/liulangye/p/2549034.html