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

    A Simple Problem with Integers
    Time Limit: 5000MS   Memory Limit: 131072K
    Total Submissions: 92632   Accepted: 28818
    Case Time Limit: 2000MS

    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.

    线段树的区间更新,区间求和裸题,感觉线段树比树状数组好理解……先照着别的的模版敲一遍再理解,线段树的写法很多人都存在差异,改成自己的比较好用

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<sstream>
    #include<cstring>
    #include<cstdio>
    #include<string>
    #include<deque>
    #include<stack>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define MM(x,y) memset(x,y,sizeof(x))
    #define LC(x) (x<<1)
    #define RC(x) (x<<1)|1
    typedef pair<int,int> pii;
    typedef long long LL;
    const double PI=acos(-1.0);
    const int N=100010;
    struct info
    {
    	LL l,r,mid;
    	LL sum;
    	LL add;
    }T[N<<2];
    LL arr[N];
    void pushup(int k)
    {
    	T[k].sum=T[LC(k)].sum+T[RC(k)].sum;
    }
    void pushdown(int k)
    {
    	T[LC(k)].add+=T[k].add;
    	T[LC(k)].sum+=T[k].add*(T[LC(k)].r-T[LC(k)].l+1);
    	T[RC(k)].add+=T[k].add;	
    	T[RC(k)].sum+=T[k].add*(T[RC(k)].r-T[RC(k)].l+1);
    	T[k].add=0;
    }
    void build(int k,LL l,LL r)
    {
    	T[k].l=l;
    	T[k].r=r;
    	T[k].add=0;
    	T[k].mid=(T[k].l+T[k].r)>>1;
    	if(l==r)
    		T[k].sum=arr[l];
    	else
    	{
    		build(LC(k),l,T[k].mid);
    		build(RC(k),T[k].mid+1,r);
    		pushup(k);
    	}	
    }
    void update(LL l,LL r,LL val,int k)
    {
    	if(r<T[k].l||l>T[k].r)
    		return ;
    	if(l<=T[k].l&&r>=T[k].r)
    	{
    		T[k].add+=val;
    		T[k].sum+=val*(T[k].r-T[k].l+1);
    	}
    	else
    	{
    		if(T[k].add)
    			pushdown(k);
    		update(l,r,val,LC(k));
    		update(l,r,val,RC(k));
    		pushup(k);
    	}
    }
    LL query(int k,LL l,LL r)
    {
    	if(l<=T[k].l&&r>=T[k].r)
    		return T[k].sum;
    	if(T[k].add)
    		pushdown(k);
    	if(r<=T[k].mid)
    		return query(LC(k),l,r);
    	else if(l>T[k].mid)
    		return query(RC(k),l,r);
    	else
    		return query(LC(k),l,T[k].mid)+query(RC(k),T[k].mid+1,r);		
    }
    int main(void)
    {
    	int tcase,n,i,m;
    	LL l,r,val;
    	char ops[3];
    	while (~scanf("%d%d",&n,&m))
    	{
    		MM(arr,0);
    		for (i=1; i<=n; i++)
    			scanf("%lld",&arr[i]);
    		build(1,1,n);
    		for (i=0; i<m; i++)
    		{
    			scanf("%s",ops);
    			if(ops[0]=='Q')
    			{
    				scanf("%lld%lld",&l,&r);
    				printf("%lld
    ",query(1,l,r));
    			}
    			else
    			{
    				scanf("%lld%lld%lld",&l,&r,&val);
    				update(l,r,val,1);
    			}
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    Note/Solution 转置原理 & 多点求值
    Note/Solution 「洛谷 P5158」「模板」多项式快速插值
    Solution 「CTS 2019」「洛谷 P5404」氪金手游
    Solution 「CEOI 2017」「洛谷 P4654」Mousetrap
    Solution Set Border Theory
    Solution Set Stirling 数相关杂题
    Solution 「CEOI 2006」「洛谷 P5974」ANTENNA
    Solution 「ZJOI 2013」「洛谷 P3337」防守战线
    Solution 「CF 923E」Perpetual Subtraction
    KVM虚拟化
  • 原文地址:https://www.cnblogs.com/Blackops/p/5766288.html
Copyright © 2011-2022 走看看