P3870 [TJOI2009]开关

码力不大,但需要注意标记下方的问题。

题解传送门:

Code:

#include<cstdio>
#include<iostream>
#define ri register int
using namespace std;

const int MAXN=100020;
int n,q,k,zuo,you;
int l[MAXN<<2],r[MAXN<<2],len[MAXN<<2],sum[MAXN<<2],tag[MAXN<<2];

inline int read()
{
    int x=0;
    char ch=getchar();
    while(ch<'0'||'9'<ch)	ch=getchar();
    while('0'<=ch&&ch<='9')
    {
        x=(x <<3)+(x <<1)+(ch-'0');
        ch=getchar();
    }
    return x;
}

void pushup(int p)
{
    sum[p]=sum[p <<1]+sum[p <<1|1];
}

void pushdown(int p)
{
    if(tag[p]&1)
    {
        sum[p <<1]=len[p <<1]-sum[p <<1];
        sum[p <<1|1]=len[p <<1|1]-sum[p <<1|1];
    }
    tag[p <<1]+=tag[p],tag[p <<1|1]+=tag[p];
    tag[p]=0;
}

void build(int p,int lft,int rit)
{
    l[p]=lft,r[p]=rit;
    if(l[p]==r[p])	{ len[p]=1; return; }
    int mid=(lft+rit)>>1;
    build(p <<1,lft,mid);
    build(p <<1|1,mid+1,rit);
    len[p]=len[p <<1]+len[p <<1|1];
}

void update(int p,int lft,int rit)
{
    if(lft<=l[p]&&r[p]<=rit)
    {
        sum[p]=len[p]-sum[p],tag[p]+=1;
        return;
    }
    pushdown(p);
    if(lft<=r[p <<1])	update(p <<1,lft,rit);
    if(l[p <<1|1]<=rit)	  update(p <<1|1,lft,rit);
    pushup(p);
}

int query(int p,int lft,int rit)
{
    if(lft<=l[p]&&r[p]<=rit)	return sum[p];
    pushdown(p);
    int ans=0;
    if(lft<=r[p <<1])	ans=query(p <<1,lft,rit);
    if(l[p <<1|1]<=rit)   ans+=query(p <<1|1,lft,rit);
    return ans;
}

int main()
{
    n=read(),q=read();
    build(1,1,n);
    for(ri i=1;i<=q;i++)
    {
        k=read(),zuo=read(),you=read();
        if(k==0)	update(1,zuo,you);
        if(k==1)	cout<<query(1,zuo,you)<<'\n';
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值