zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    Xamarin.Android开发实践(十八)
    Xamarin.Android开发实践(十七)
    smokeping网络监控
    Cobbler自动化部署
    在线编辑器KindEditor的使用
    前端之快速创建标签
    Tornado之自定义异步非阻塞的服务器和客户端
    算法基础知识之树、二叉树
    Tornado之实例和扩展
    Scrapy源码研究前戏
  • 原文地址:https://www.cnblogs.com/liulangye/p/2549034.html
Copyright © 2011-2022 走看看