poj3468 A Simple Problem with Integers 线段树区间更新,区间求和

来源:互联网 发布:高校工资知乎 编辑:程序博客网 时间:2024/05/16 17:35

传送门:poj3468 A Simple Problem with Integers

题目大意

输入:第一行输入两个数N和Q。N代表有多少个元素,Q代表进行多少次操作
第二行数输入n个数 表示对应的初始值
然后下面的Q行代表操作:
C a b c把a到b区间的数增加c
Q a b输出a到b区间的数量之和
输出:每当有Q操作输出a到b区间的数量之和

解题思路

如果总是WA的话,可以测试这个数据:

10 221 2 3 4 5 6 7 8 9 10Q 4 4C 1 10 3C 6 10 3C 6 9 3C 8 9 -100C 7 9 3C 7 10 3C 1 10 3Q 6 10Q 6 9Q 8 9Q 7 9Q 7 10Q 1 10Q 2 4C 3 6 3Q 9 9Q 1 1Q 5 5Q 6 6Q 7 7Q 6 8ans4-82-104-147-122-100-3727-737142125-28

如果错的话,考虑一下是不是标记的事情,这道题目标记是可以重叠的。
你测试一下这个数据就知道了

10 221 2 3 4 5 6 7 8 9 10C 1 10 3Q 6 10C 6 10 3Q 6 10Q 8 8

AC代码

#include<cstdio>const int MAXN = 200005;#define lson left,mid,rt<<1#define rson mid+1,right,rt<<1|1typedef long long LL;  //lldlong long ans;struct Node{    int left;    int right;    long long  value;    long long addMark;    int mid()    {        return (left+right)>>1;    }}tree[MAXN*4];void pushUp(int rt){    tree[rt].value = tree[rt<<1].value + tree[rt<<1|1].value;}void pushDown(int rt){    if(tree[rt].addMark !=0)    {        int m = (tree[rt].right - tree[rt].left+1);        tree[rt<<1].value += ((m-m/2)*(tree[rt].addMark/m));        tree[rt<<1|1].value += ((m/2)*(tree[rt].addMark/m));        //在这道题目当中这里是+=不是=        tree[rt<<1].addMark += ((m-m/2)*(tree[rt].addMark/m));        tree[rt<<1|1].addMark += ((m/2)*(tree[rt].addMark/m));        tree[rt].addMark = 0;    }}void buildTree(int left,int right,int rt){    tree[rt].left = left;    tree[rt].right= right;    tree[rt].addMark = 0;    if(left == right)    {        scanf("%lld",&tree[rt].value);        return ;    }    int mid = tree[rt].mid();    buildTree(lson);    buildTree(rson);    pushUp(rt);}void updateTree(int left,int right,int rt,int L,int R,int val){    pushDown(rt);    if(left>=L && right<=R)    {        tree[rt].addMark +=(tree[rt].right - tree[rt].left+1)*val;        tree[rt].value += (tree[rt].right - tree[rt].left+1)*val;        return ;    }    int mid = tree[rt].mid();    if(L<=mid)        updateTree(lson,L,R,val);    if(R>mid)        updateTree(rson,L,R,val);    pushUp(rt);}void queryTree(int left,int right,int rt,int L,int R){    pushDown(rt);    if(left>=L && right<=R)    {        ans += tree[rt].value;        //printf("[%d]\n",ans);        return ;    }    int mid = tree[rt].mid();    if(L<=mid)        queryTree(lson,L,R);    if(R>mid)        queryTree(rson,L,R);}int main(){    int n,q;    char ch;    int a,b,c;    while(scanf("%d%d",&n,&q)!=EOF)    {        buildTree(1,n,1);        while(q--)        {            getchar();            scanf("%c",&ch);            if(ch == 'C')            {                scanf("%d%d%d",&a,&b,&c);                updateTree(1,n,1,a,b,c);            }            else if(ch == 'Q')            {                scanf("%d%d",&a,&b);                ans = 0;                queryTree(1,n,1,a,b);                printf("%lld\n",ans);            }        }    }    return 0;}
0 0