zoukankan      html  css  js  c++  java
  • 线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和

    poj3468 A Simple Problem with Integers
    题意:O(-1)
    思路:O(-1)

    线段树功能:update:成段增减 query:区间求和

    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.

    题目大意:  

    N个数 M个操作 每个操作分Q a b得区间(a,b)的和;C a b c 区间[a,b]里面每个元素的value加c 

    由于是成段更新 要用到延迟标记type; 每次C操作 只更新到和某个节点的区间范围一致,下次在访问的时候 延迟标记下移


    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    const int maxn = 111111;
    struct Tree{
    	__int64 value;
    	__int64 type;
    }tree[maxn<<2];
    
    
    void PushUp(int rt) {
    	tree[rt].value = tree[rt<<1].value + tree[rt<<1|1].value;
    }
    void PushDown(int rt,int ms) {
    	if (tree[rt].type) {
    		tree[rt<<1].type += tree[rt].type;
    		tree[rt<<1|1].type += tree[rt].type ;
    		tree[rt<<1].value += (ms - (ms >> 1)) * tree[rt].type;
    		tree[rt<<1|1].value += (ms >> 1) * tree[rt].type;
    		tree[rt].type = 0;
    	}
    }
    void build(int l,int r,int rt) {
    	tree[rt].type=0;
    	__int64 val;
    	if (l == r){
    		scanf("%I64d",&val);
    		tree[rt].value=val;
    		return ;
    	}
    	int m = (l + r) >> 1;
    	build(lson);
    	build(rson);
    	PushUp(rt);
    }
    void update(int L,int R,int c,int l,int r,int rt) {
    	if (L <= l && r <= R) {//标记1  //更新到这就行,不一定更新到最底端
    		tree[rt].type += c;
    		tree[rt].value += c * (r - l + 1);
    		return ;
    	}
    	PushDown(rt , r - l + 1);//延迟标记,这时候后推, (标记2)
    	//比如建了 [1,4]  然后我们第一次的时候是更新[1,2]
    	// [1,2][3,4]  [1,2]的type就是非0,value往上更新;
    	//   [1][2][3][4]  第二次如果还是要更新[1,2] 在标记1直接更新
    	int m = (l + r) >> 1;   // 而如果你是要更新[1,1](必定访问到标记2) 那么先进行标记2 让两儿子的value更新 
    	if (L <= m) update(L , R , c , lson); //记得这时候儿子type被赋值,自己type=0;
    	if (R > m) update(L , R , c , rson);
    	PushUp(rt);
    }
    __int64 query(int L,int R,int l,int r,int rt) {  
        if (L <= l && r <= R) {  
            return tree[rt].value;  
        }  
    	PushDown(rt , r - l + 1); //注意这里
        int m = (l + r) >> 1;     //如果之前标记[1,4]type!=0 然后我们现在
        __int64 ret = 0;         //如果是访问[1,4]第一步直接得到返回值是没有问题
        if (L <= m) ret += query(L , R , lson);  //但访问[1,3]的时候要要把之前的[1,4]延迟标记下移
        if (R > m) ret += query(L , R , rson);  
        return ret;  
    }  
    int main() {
    	int N , Q;
    	scanf("%d%d",&N,&Q);
    	build(1 , N , 1);
    	while (Q --) {
    		char op[2];
    		int a , b , c;
    		scanf("%s",op); //防止用%c 会接受回车 新技能get√
    		if (op[0] == 'Q') {
    			scanf("%d%d",&a,&b);
    			printf("%lld
    ",query(a , b , 1 , N , 1));
    		} else {
    			scanf("%d%d%d",&a,&b,&c);
    			update(a , b , c , 1 , N , 1);
    		}
    	}
    	return 0;
    }


    版权声明:本文为博主原创文章,未经博主允许不得转载。

    today lazy . tomorrow die .
  • 相关阅读:
    Android 系统开发做什么?
    MySQL索引-B+树
    转:redis雪崩、穿透、击穿
    转:django3上线部署踩得坑
    nginx、uwsgi部署django中session丢失得问题
    类型转换(数字转字符串等)
    JS基础篇1:数据类型(8种)
    css3动画与js动画的区别
    drag拖拽事件
    三栏布局,中间自适应
  • 原文地址:https://www.cnblogs.com/france/p/4808773.html
Copyright © 2011-2022 走看看