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

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


    A Simple Problem with Integers

    Time Limit: 5000MS Memory Limit: 131072K
    Total Submissions: 77302 Accepted: 23788
    Case Time Limit: 2000MS

    Description


    You have N integers, A1, A2, ... , 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 A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
    Each of the next Q lines represents an operation.
    "C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
    "Q a b" means querying the sum of Aa, Aa+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.

    Source

    POJ Monthly--2007.11.25, Yang Yi

    大意——给你n个数字组成的序列。

    你将可以对它们进行两种操作,一种是对于当前给定区间里的数字都加上一个数,还有一种是对于当前给定区间里的数字进行求和。


    思路——表面上看起来是用线段树解决,但实际上将问题略微处理一下就能够用树状数组来解决。并且效率更高。

    处理例如以下:假设给区间[l,r]都加上一个数x的话,我们令s(i)=加上x之前的前i项和,s’(i)=加上x之后的前i项和,那么就有当i<l时,s’(i)=s(i);当l<=i<=r时。s’(i)=s(i)+x*(i-l+1)=s(i)+x*i
    -x*(l-1);当i>r时,s’(i)=s(i)+x*(r-l+1)。那么我们就能够建立两个树状数组,从而将问题简化。详细參见:csdn博客:http://blog.csdn.net/u013068502/article/details/47252335。


    复杂度分析——时间复杂度:O(log(n!)+q*log(ab)),空间复杂度:O(n)

    附上AC代码:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cmath>
    #include <iomanip>
    #include <ctime>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <set>
    #include <map>
    using namespace std;
    typedef unsigned int UI;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double LD;
    const double pi = acos(-1.0);
    const double e = exp(1.0);
    const double eps = 1e-8;
    const int maxn = 100005;
    LL bit1[maxn], bit2[maxn]; // 代表两个树状数组。数组1用来存储初始值,
    						   // 数组2用来存储变化的值
    int n, query; // 初始数组大小。问题的个数
    char op[5]; // 选择哪种操作
    
    int lowbit(int x);
    void update(LL * bit, int x, int add);
    LL sum(LL * bit, int x);
    
    int main()
    {
    	ios::sync_with_stdio(false);
    	int a, b, c, x;
    	while (~scanf("%d%d", &n, &query))
    	{
    		memset(bit1, 0, sizeof(bit1));
    		memset(bit2, 0, sizeof(bit2));
    		// 上面清空数组。避免上次结果干扰
    		for (int i=1; i<=n; i++)
    		{
    			scanf("%d", &x);
    			update(bit1, i, x); // 将初始值存入数组1
    		}
    		while (query--)
    		{
    			scanf("%s%d%d", op, &a, &b);
    			if (op[0] == 'C')
    			{
    				scanf("%d", &c);
    				update(bit1, a, (-c)*(a-1));
    				update(bit2, a, c);
    				// 上面更新改变状态
    				update(bit1, b+1, c*b);
    				update(bit2, b+1, (-c));
    				// 上面去掉反复状态
    			}
    			else
    			{
    				LL ans = 0;
    				ans += sum(bit1, b)+sum(bit2, b)*b;
    				ans -= sum(bit1, a-1)+sum(bit2, a-1)*(a-1);
    				printf("%lld
    ", ans);
    			}
    		}
    	}
    	return 0;
    }
    
    int lowbit(int x) // 求2^k,k表示x为二进制时末尾的0的个数
    {
    	return (x&(-x));
    }
    
    void update(LL * bit, int x, int add)
    { // 更新节点信息(加上数add)
    	while (x!=0 && x<=n)
    	{
    		bit[x] += add;
    		x += lowbit(x);
    	}
    }
    
    LL sum(LL * bit, int x)
    { // 区间求和(求1~x之间数组的和)
    	LL res = 0;
    	while (x > 0)
    	{
    		res += bit[x];
    		x -= lowbit(x);
    	}
    	return res;
    }
    


  • 相关阅读:
    docker network
    mongodb索引
    docker中管理数据
    mysql表备份及还原
    Find and run the whalesay image
    Learn about images & containers
    docker installation on ubuntu
    【转载】熟练利用google hacking来辅助我们快速渗透
    xmind常用快捷键
    漏洞挖掘基础
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7185609.html
Copyright © 2011-2022 走看看