ST

ST

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述

“麻雀”lengdan用随机数生成了后台数据,但是笨笨的他被妹纸的问题给难住了。。。

已知lengdan生成了N(1=<N<=10005)个随机整数,妹子对这些数可能有以下几种操作或询问:

1,A a b c 表示给区间a到b内每个数都加上c;

2,S a b  表示输出区间a到b内的和;

3,Q a b 表示区间a到b内的奇数的个数;

为了使妹纸不口渴,所以我们决定妹纸的询问次数少一点,即(1=<M<=10000,M为询问次数)。

唉,你说妹纸一直进行操作1该多好啊,嘎嘎。。。

好水!喝饱了~~~

输入
多组测试数据。
每组测试数据第一行包含两个数N,M,表示N个整数,执行M次询问或操作。
紧接着一行输入N个整数,输入数据保证在int范围内。
接下来M行,每行输入一种操作。
输出
每次对于操作2和3,输出结果。
样例输入
5 5
1 2 3 4 5
Q 1 4
S 1 5
A 1 4 1
S 1 5
Q 2 5
样例输出
2
15
19
3
一个数加上奇数,奇偶发生变化
#include<stdio.h>
#include<string.h>
#define ll long long
#define maxn 10010
struct node
{
    ll l,r,mid,lazysum,odd,sum,lazyodd; 
} st[maxn*4];
long long int a[10000];
void jianshu(ll l,ll r,ll tr)   //建树
{
    if(l==r)
    {
        st[tr].l=l,st[tr].r=r,st[tr].sum=a[l],st[tr].odd=a[l]&1;
        return;
    }
    st[tr].mid=(l+r)>>1;
    st[tr].l=l,st[tr].r=r,st[tr].odd=0,st[tr].lazyodd=0,st[tr].lazysum=0;//清零
    jianshu(l,st[tr].mid,tr<<1),jianshu(st[tr].mid+1,r,tr<<1|1);
    st[tr].sum=st[tr<<1].sum+st[tr<<1|1].sum;
    st[tr].odd=st[tr<<1].odd+st[tr<<1|1].odd;
}
void gengxin(ll x,ll y,ll z,ll tr)  //更新
{
    if(st[tr].lazyodd&&st[tr].l!=st[tr].r)  //若有lazyodd,且不是叶子节点
    {
        st[tr<<1].lazyodd^=1,st[tr<<1|1].lazyodd^=1;  //子节点的lazyodd若为0,就变成1,若为1,就变成0
        st[tr<<1].odd=st[tr<<1].r-st[tr<<1].l+1-st[tr<<1].odd;//无论子节点的lazyodd是否为1,均更新子节点的odd个数
        st[tr<<1|1].odd=st[tr<<1|1].r-st[tr<<1|1].l+1-st[tr<<1|1].odd;
        st[tr].lazyodd=0;   //向子节点传递lazyodd后,清零
    }
    if(st[tr].l==x&&st[tr].r==y)
    {
        st[tr].lazysum+=z;  //更新lazysum
        st[tr].sum+=(y-x+1)*z;
        if(z&1)
            st[tr].lazyodd^=1,st[tr].odd=st[tr].r-st[tr].l+1-st[tr].odd;  //若要加的数为奇数,
        return ;
    }
    else if(y<=st[tr].mid)
        gengxin(x,y,z,tr<<1);
    else if(x>st[tr].mid)
        gengxin(x,y,z,tr<<1|1);
    else
        gengxin(x,st[tr].mid,z,tr<<1),gengxin(st[tr].mid+1,y,z,tr<<1|1);
    st[tr].sum+=(y-x+1)*z;//重要,要是没有找到此区间,就更新
    if(z&1)
        st[tr].odd=st[tr<<1].odd+st[tr<<1|1].odd;
}
ll chaxun1(ll x,ll y,ll tr)
{
    if(st[tr].lazyodd&&st[tr].l!=st[tr].r)
    {
        st[tr<<1].lazyodd^=1,st[tr<<1|1].lazyodd^=1;
        st[tr<<1].odd=st[tr<<1].r-st[tr<<1].l+1-st[tr<<1].odd;
        st[tr<<1|1].odd=st[tr<<1|1].r-st[tr<<1|1].l+1-st[tr<<1|1].odd;
        st[tr].lazyodd=0;
    }
    if(st[tr].l==x&&st[tr].r==y)
        return st[tr].odd;
    else if(st[tr].mid>=y)
        return chaxun1(x,y,tr<<1);
    else if(st[tr].mid<x)
        return chaxun1(x,y,tr<<1|1);
    else
        return chaxun1(x,st[tr].mid,tr<<1)+chaxun1(st[tr].mid+1,y,tr<<1|1);
}
ll chaxun(ll x,ll y,ll tr)
{
    if(st[tr].lazysum&&st[tr].l!=st[tr].r)
    {
        st[tr<<1].lazysum+=st[tr].lazysum;
        st[tr<<1|1].lazysum+=st[tr].lazysum;
        st[tr<<1].sum+=(st[tr<<1].r-st[tr<<1].l+1)*st[tr].lazysum;
        st[tr<<1|1].sum+=(st[tr<<1|1].r-st[tr<<1|1].l+1)*st[tr].lazysum;
        st[tr].lazysum=0;
    }
    if(st[tr].l==x&&st[tr].r==y)
        return st[tr].sum;
    else if(y<=st[tr].mid)
        return chaxun(x,y,tr<<1);
    else if(x>st[tr].mid)
        return chaxun(x,y,tr<<1|1);
    else
        return chaxun(x,st[tr].mid,tr<<1)+chaxun(st[tr].mid+1,y,tr<<1|1);
}
int main()
{
    ll n,m,i,j,x,z,y;
    while(scanf("%lld%lld",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        char c[10];
        jianshu(1,n,1);
        while(m--)
        {
            scanf("%s",c);
            scanf("%lld%lld",&x,&y);
            if(c[0]=='S')
                printf("%lld\n",chaxun(x,y,1));
            else if(c[0]=='Q')
                printf("%lld\n",chaxun1(x,y,1));
            else
            {
                scanf("%lld",&z);
                gengxin(x,y,z,1);
            }
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值