• POJ3468 A Simple Problem With Integers 树状数组 区间更新区间询问


    今天学了很多关于树状数组的技巧。一个是利用树状数组可以简单的实现段更新,点询问(二维的段更新点询问也可以),每次修改只需要修改2个角或者4个角就可以了,另外一个技巧就是这题,原本用线段树做,现在可以用树状数组做的题,只需多维护一个bit即可。具体的思路见下面的链接:

    http://hi.baidu.com/billdu/item/053f6a15ca301b0a8ebde400

    要理解里面的橙色块求的时候是打竖看的,不是打横看的。

    #pragma warning(disable:4996)
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #define ll long long
    #define maxn 100000
    #define lowbit(k) k&(-k)
    using namespace std;
    
    ll bit[2][maxn + 50];
    int n,q;
    
    void inc(ll bit[],int i, int m)
    {
    	for (; i <= n; i += lowbit(i)) bit[i] += m;
    }
    
    ll query(ll bit[],int i)
    {
    	ll sum = 0;
    	for (; i > 0; i -= lowbit(i)){
    		sum += bit[i];
    	}
    	return sum;
    }
    
    ll sum[maxn + 50];
    
    int main()
    {
    	while (cin >> n >> q)
    	{
    		memset(bit, 0, sizeof(bit));
    		for (int i = 1; i <= n; i++){
    			scanf("%lld", sum + i);
    		}
    		sum[0] = 0;
    		for (int i = 1; i <= n; i++) sum[i] += sum[i - 1];
    		char str[3];
    		int a,b,c;
    		for (int i = 0; i < q; i++){
    			scanf("%s", str);
    			if (str[0] == 'Q'){
    				scanf("%d%d", &a, &b);
    				ll ans = (query(bit[0], b)*(b + 1) - query(bit[1], b)) - (query(bit[0], a - 1)*a - query(bit[1], a - 1));
    				ans += sum[b] - sum[a - 1];
    				printf("%lld
    ", ans);
    			}
    			else{
    				scanf("%d%d%d", &a, &b, &c);
    				inc(bit[0], a, c);
    				inc(bit[1], a, c*a);
    				inc(bit[0], b + 1, -c);
    				inc(bit[1], b + 1, -c*(b + 1));
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    23 数字时钟&长图滚动
    22 日期特效&长图滚动
    彻底澄清c/c++指针概念
    已管理员模式运行批处理路径丢失问题的解决方法
    使用mathjax在博客中完美显示数学公式,支持PC,手机浏览器
    GOOGLE高级搜索技巧
    我要搬家
    简单的3proxy配置
    AutoMapper小结
    专业IT培训机构-传智播客
  • 原文地址:https://www.cnblogs.com/chanme/p/3555084.html
Copyright © 2020-2023  润新知