POJ 3468

来源:互联网 发布:java内存泄露例子 编辑:程序博客网 时间:2024/05/29 14:47
思路:线段树,节点区间的和由sum和add组成,更新:当区间正好匹配时就直接node[k].add += add,return,否则把和加在sum里,递归更新子区间。查找时:如果区间匹配就直接返回node[k].sum + (node[k].right - node[k].left + 1) * node[k].add,否则将和加在sum中,add向子区间传递。

/*************************************************************************    > File Name:        inter.cpp    > Author:         wangzhili    > Mail:           wangstdio.h@gmail.com    > Created Time:   2014/2/27 星期四 14:16:52 ************************************************************************/#include<iostream>#include<cstdio>using namespace std; #define MAX 100005 class TreeNode{    public:        int left;         int right;         int mid;         long long int sum;         long long int add; }; TreeNode node[4*MAX];void BuildTree(int k, int l, int r){    node[k].left = l;     node[k].right = r;    node[k].mid = (l + r) >> 1;     node[k].sum = 0;     node[k].add = 0;     if(l == r)        return ;     int mid = (l + r) >> 1;     BuildTree(k << 1, l, mid);     BuildTree(k << 1|1, mid+1, r); }void UpdateTree(int k, int l, int r, long long int add){    if(node[k].left == l && node[k].right == r)    {        node[k].add += add;         return ;     }    node[k].sum += (r-l+1) * add;     if(node[k].mid < l)        UpdateTree(k << 1|1, l, r, add);     else if(node[k].mid >= r)        UpdateTree(k << 1, l, r, add);     else    {        UpdateTree(k << 1, l, node[k].mid, add);         UpdateTree(k << 1|1, node[k].mid + 1, r, add);     }}long long int GetSum(int k, int l, int r){    if(node[k].left == l && node[k].right == r)        return node[k].sum + (node[k].right - node[k].left + 1) * node[k].add;     node[k << 1].add += node[k].add;     node[k << 1|1].add += node[k].add;     node[k].sum += (node[k].right - node[k].left + 1) * node[k].add;     node[k].add = 0;     if(node[k].mid < l)        return GetSum(k << 1|1, l, r);     else if(node[k].mid >= r)        return GetSum(k << 1, l, r);     else        return GetSum(k << 1, l, node[k].mid) + GetSum(k << 1|1, node[k].mid + 1, r); }int main(int argc, char const *argv[]) {    int n, i, m, l, r, num;     char str[2];     freopen("in.c", "r", stdin);     while(~scanf("%d%d", &n, &m))    {        BuildTree(1, 1, n);         for(i = 1; i <= n; i ++)        {            scanf("%d", &num);             UpdateTree(1, i, i, num);         }        for(i = 0; i < m; i ++)        {            scanf("%s", str);            if(str[0] == 'Q')            {                scanf("%d%d", &l, &r);                 printf("%lld\n", GetSum(1, l, r));             }            else            {                scanf("%d%d%d", &l, &r, &num);                 UpdateTree(1, l, r, num);             }        }    }    return 0; }


0 0