poj 3468 区间更新or求和

来源:互联网 发布:安卓修改mac地址软件 编辑:程序博客网 时间:2024/04/30 12:03

Problem:
给一个数组,多次更新一段区间的值,或者查询一段区间的和。
Solutioin:
利用线段树实现高效的反复查询的工作。

#include<cstdio>#include<iostream>#include<sstream>#include<cstdlib>#include<cmath>#include<cctype>#include<string>#include<cstring>#include<algorithm>#include<stack>#include<queue>#include<set>#include<map>#include<ctime>#include<vector>#include<fstream>#include<list>using namespace std;#define ms(s) memset(s,0,sizeof(s))typedef unsigned long long ULL;typedef long long LL;const double PI = 3.141592653589;const int INF = 0x3fffffff;#define maxn 100000struct node{    int l, r;    LL sum, inc;    int mid(){        return (l+r)/2;    }};node Tree[maxn*4];LL value[maxn+10];//初始化树,根节点是1void init_tree(int root, int l, int r){    Tree[root].l = l;    Tree[root].r = r;    Tree[root].inc = 0;    if(l == r){        Tree[root].sum = value[l];    }    else{        init_tree(2*root, l, (l+r)/2);        init_tree(2*root+1, (l+r)/2 + 1, r);        Tree[root].sum = Tree[2*root].sum + Tree[2*root+1].sum;    }}//查找和LL query_tree(int root, int l, int r){    int m = Tree[root].mid();    if(l == Tree[root].l && r == Tree[root].r)        return Tree[root].sum + Tree[root].inc*(r-l+1);    else{        Tree[2*root].inc += Tree[root].inc;        Tree[2*root+1].inc += Tree[root].inc;        Tree[root].sum += Tree[root].inc * (Tree[root].r-Tree[root].l+1);        Tree[root].inc = 0;        if(l > m){            return query_tree(2*root+1, l, r);        }        else if(r <= m)            return query_tree(2*root, l, r);        else            return query_tree(2*root, l, m) + query_tree(2*root+1, m+1, r);    }}void update_tree(int root, int l, int r, LL v){    int m = Tree[root].mid();    if(Tree[root].l == l && Tree[root].r == r)        Tree[root].inc += v;    else{        Tree[root].sum += v*(r-l+1);        if(l > m){            update_tree(2*root+1, l, r, v);        }        else if(r <= m)            update_tree(2*root, l, r, v);        else{            update_tree(2*root, l, m, v);            update_tree(2*root+1, m+1, r, v);        }    }}int main(){//        freopen("/Users/really/Documents/code/input","r",stdin);    //    freopen("/Users/really/Documents/code/output","w",stdout);    ios::sync_with_stdio(false);    ms(Tree);    int n, q;    int a, b, c;    cin >> n >> q;    string s;    for(int i = 1; i <= n; ++i)        cin >> value[i];    init_tree(1, 1, n);    for(int i = 1; i <= q; ++i){        cin >> s;        if(s == "Q"){            cin >> a >> b;            cout << query_tree(1, a, b) << endl;        }        else{            cin >> a >> b >> c;            update_tree(1, a, b, c);        }    }    return 0;}
1 0
原创粉丝点击