线段树

来源:互联网 发布:店铺复制软件 编辑:程序博客网 时间:2024/06/05 11:10
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define LL long longLL x[10010],sum;struct Node{    LL l,r,sum,flag,odd,even;} node[100010];void build_tree(LL l,LL r,LL n)//建树{    node[n].flag=0,node[n].l=l,node[n].r=r;    if(l==r)    {        node[n].sum=x[l];        if(x[l]&1ll)            node[n].odd=1ll,node[n].even=0;        else            node[n].odd=0,node[n].even=1ll;        return ;    }    LL mid=(l+r)>>1ll,L=n<<1ll,R=(n<<1ll)|1ll;    build_tree(l,mid,L);    build_tree(mid+1ll,r,R);    node[n].sum=node[L].sum+node[R].sum;    node[n].odd=node[L].odd+node[R].odd;    node[n].even=node[L].even+node[R].even;}void pushdown(LL n)//下放{    if(node[n].flag!=0)    {        LL L=n<<1ll,R=(n<<1ll)|1ll;        if(node[n].flag&1ll)        {            swap(node[L].odd,node[L].even);            swap(node[R].odd,node[R].even);        }        node[L].flag+=node[n].flag,node[R].flag+=node[n].flag;//标记下放子节点        node[L].sum+=(node[L].r-node[L].l+1ll)*node[n].flag;//更新子节点的值        node[R].sum+=(node[R].r-node[R].l+1ll)*node[n].flag;//同上        node[n].flag=0;//清空标记    }}void update(LL l,LL r,LL add,LL n)//更新{    if(node[n].l==l&&node[n].r==r)    {        node[n].flag+=add;        node[n].sum+=(node[n].r-node[n].l+1ll)*add;//更新当前节点值        if(add&1ll) swap(node[n].odd,node[n].even);        return ;    }    pushdown(n);    LL mid=(node[n].l+node[n].r)>>1ll,L=n<<1ll,R=(n<<1ll)|1ll;    if(r<=mid)        update(l,r,add,L);    else if(l>mid)        update(l,r,add,R);    else        update(l,mid,add,L),update(mid+1ll,r,add,R);    node[n].sum=node[L].sum+node[R].sum;    node[n].odd=node[L].odd+node[R].odd;    node[n].even=node[L].even+node[R].even;}void Search(LL l,LL r,LL n,char s)//查询{    if(node[n].l==l&&node[n].r==r)    {        if(s=='S') sum+=node[n].sum;        else sum+=node[n].odd;        return ;    }    pushdown(n);    LL mid=(node[n].l+node[n].r)>>1ll,L=(n<<1ll),R=(n<<1ll)|1ll;    if(r<=mid)        Search(l,r,L,s);    else if(l>mid)        Search(l,r,R,s);    else        Search(l,mid,L,s),Search(mid+1ll,r,R,s);}int main(){    //freopen("Input.txt","r",stdin);    //freopen("Output.txt","w",stdout);    LL n,m;    while(~scanf("%lld%lld",&n,&m))    {        memset(x,0,sizeof(x));        memset(node,0,sizeof(node));        for(int i=1; i<=n; i++)            scanf("%lld",&x[i]);        build_tree(1ll,n,1ll);        while(m--)        {            char s[5];            scanf("%s",s);            if(s[0]=='A')            {                LL a,b,c;                scanf("%lld%lld%lld",&a,&b,&c);                update(a,b,c,1ll);            }            else            {                sum=0;                LL a,b;                scanf("%lld%lld",&a,&b);                Search(a,b,1ll,s[0]);                printf("%lld\n",sum);            }        }    }}
0 0
原创粉丝点击