zoukankan      html  css  js  c++  java
  • poj 3468A Simple Problem with Integers

    Description

    You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

    Input

    The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
    The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
    Each of the next Q lines represents an operation.
    "C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
    "Q a b" means querying the sum of AaAa+1, ... , Ab.

    Output

    You need to answer all Q commands in order. One answer in a line.

    Sample Input

    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 4 4
    Q 1 10
    Q 2 4
    C 3 6 3
    Q 2 4
    

    Sample Output

    4
    55
    9
    15

    Hint

    The sums may exceed the range of 32-bit integers.

    这题是线段树成段更新,看别人代码想了很久。
    思路:开一个结构体,含有左右边界l,r,这段区间线段总和sum,更新标志ans(整段区间内每个数要加的数值)。
    每次一个区间更新(即加一个数value)的时候,从第一个线线段开始向下判断,如果更新的区间刚好是这条线段的区间,那么直接加上更新的数值value并返回,否则整段区间的sum值变为sum+(b-a+1)*value,再在子节点中找直到找到区间大小加好符合的时候,ans=ans+value,返回。
    每一次询问,从第一个线段开始向下,如果区间刚好符合,那么返回区间的sum否则把这条线段的更新标志往子节点传,同时这条线段的更新标志变为0.这里我采用的是每一次更新就把每根点段的总和都保存在sum中,这样询问的时候就不用麻烦的加上b[i].ans*(b[i].r-b[i].l+1).


    #include<stdio.h>
    #include<string.h>
    #define maxn 100005
    #define ll long long
    char str[10];
    ll a[maxn];
    struct node
    {
    	ll l,r,sum,ans;
    }b[4*maxn];
    
    void build(ll l,ll r,ll i)
    {
        ll mid;
        b[i].l=l;
        b[i].r=r;
        b[i].ans=0;
        if(b[i].l==b[i].r)
        {
           b[i].sum=a[l];
           return;
        }
        mid=(l+r)/2;
        build(l,mid,2*i);
        build(mid+1,r,i*2+1);
        b[i].sum=b[i*2].sum+b[i*2+1].sum;
    }
    
    void pushdown(int i)
    {
        if(b[i].ans){
            b[i*2].ans+=b[i].ans;
            b[i*2+1].ans+=b[i].ans;
            b[i*2].sum+=b[i].ans*(b[i*2].r-b[i*2].l+1);
            b[i*2+1].sum+=b[i].ans*(b[i*2+1].r-b[i*2+1].l+1);
            b[i].ans=0;
        }
    }
    
    
    void add(ll l,ll r,ll value,ll i)
    {
    	ll mid;
    	if(b[i].l==l && b[i].r==r)
    	{
    	   b[i].ans=b[i].ans+value;
    	   b[i].sum+=(b[i].r-b[i].l+1)*value;
    	   return;
    	}
    	pushdown(i);
    	b[i].sum+=(r-l+1)*value; //这一句写了,下面第二句就不用写了,是同一个意思
    	mid=(b[i].l+b[i].r)/2;
    	if(l>mid)
    	add(l,r,value,i*2+1);
    	else if(r<=mid)
    	add(l,r,value,i*2);
    	else
    	{
    	   add(l,mid,value,i*2);
    	   add(mid+1,r,value,i*2+1);
    	}
    	//b[i].sum=b[i*2].sum+b[i*2+1].sum;  ---2
    }
    
    ll question(ll l,ll r,ll i)
    {
    	ll mid;
    	if(b[i].l==l && b[i].r==r)
    	{
    	   return b[i].sum;
    	}
    	pushdown(i);
    	mid=(b[i].l+b[i].r)/2;
    	if(l>mid)
    	return question(l,r,i*2+1);
    	else if(r<=mid)
    	return question(l,r,i*2);
    	else if(l<=mid && r>mid)
    	return question(l,mid,i*2)+question(mid+1,r,i*2+1);
    
    }
    
    int main()
    {
    	ll n,m,c,d,e,i,j;
    	while(scanf("%lld%lld",&n,&m)!=EOF)
    	{
    		for(i=1;i<=n;i++)
    		scanf("%lld",&a[i]);
    		build(1,n,1);
    		while(m--)
    		{
    			scanf("%s",str);
    			if(str[0]=='Q')
    			{
    				scanf("%lld%lld",&c,&d);
    				printf("%lld
    ",question(c,d,1));
    			}
    			else if(str[0]=='C')
    			{
    				scanf("%lld%lld%lld",&c,&d,&e);
    				add(c,d,e,1);
    			}
    		}
    	}
    	return 0;
    }
    


    
    
  • 相关阅读:
    【转】关于维生素的那些事
    【转】MaBatis学习---源码分析MyBatis缓存原理
    【转】Spring学习---Bean配置的三种方式(XML、注解、Java类)介绍与对比
    【转】Java学习---垃圾回收算法与 JVM 垃圾回收器综述
    Qt 中的对象模型(Object Model)
    The Property System
    Qt--core模块概述
    QtCore概述
    在Android Studio中下载Android SDK的两种方式(Android Studio3.0、windows)
    同一个进程的多个线程堆栈共享状况
  • 原文地址:https://www.cnblogs.com/herumw/p/9464861.html
Copyright © 2011-2022 走看看