BZOJ1230&&P2846 [USACO08NOV]光开关Light Switching

线段树01区间翻转,挺裸的,就是区间+1%2,然后求和

代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=500500;
struct Tree
{
    int son[2],bond[2];
    int la,asum;
}t[M];
int n,m;
string s;
int num[M],cnt=1,rt=0;
inline int read()
{
    int x=0;char ch=getchar();
    while (ch>'9'||ch<'0') ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x;
}
inline void up(int x)
{
    int ls=t[x].son[0];
    int rs=t[x].son[1];
    t[x].asum=t[ls].asum+t[rs].asum;
    t[x].bond[0]=t[ls].bond[0];
    t[x].bond[1]=t[rs].bond[1];
    return ;
}
inline void built(int l,int r,int cur)
{
    if (l==r) 
    {
        t[cur].asum=num[l];
        t[cur].bond[0]=t[cur].bond[1]=l;
        t[cur].son[0]=t[cur].son[1]=-1;
        return ; 
    }
    t[cur].son[0]=cnt++;
    t[cur].son[1]=cnt++;
    int mid=(l+r)>>1;
    built(l,mid,t[cur].son[0]);
    built(mid+1,r,t[cur].son[1]);
    return (void)(up(cur));
}
inline void down(int x)
{
    if (t[x].la%2==0) return ;
    int ls=t[x].son[0];
    int rs=t[x].son[1];
    t[ls].asum=(t[ls].bond[1]-t[ls].bond[0]+1-t[ls].asum);
    t[rs].asum=(t[rs].bond[1]-t[rs].bond[0]+1-t[rs].asum);
    t[ls].la++;t[rs].la++;t[x].la=0;
    return ;
}
inline void date(int l,int r,int val,int cur)
{
    if (l<=t[cur].bond[0]&&t[cur].bond[1]<=r)
    {
        t[cur].asum=(t[cur].bond[1]-t[cur].bond[0]+1-t[cur].asum);
        return (void)(t[cur].la++);
    }
    down(cur);
    int mid=(t[cur].bond[0]+t[cur].bond[1])>>1;
    if (l<=mid) date(l,r,val,t[cur].son[0]);
    if (r>mid) date(l,r,val,t[cur].son[1]);
    return (void)(up(cur));
}
inline int query(int l,int r,int x)
{
    if (l<=t[x].bond[0]&&t[x].bond[1]<=r) return t[x].asum;
    down(x);up(x);int tot=0;
    int mid=(t[x].bond[0]+t[x].bond[1])>>1;
    if (l<=mid) tot+=query(l,r,t[x].son[0]);
    if (r>mid) tot+=query(l,r,t[x].son[1]);
    return tot; 
}
signed main()
{
    n=read();m=read();built(1,n,rt);
    while (m--)
    {
        int a=read(),b=read(),c=read();
        if (a==0) date(b,c,1,rt);
        else cout<<query(b,c,rt)<<endl;
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值