【解题报告】洛谷P3870 开关
【解题报告】洛谷P3870 开关
题目链接
https://www.luogu.com.cn/problem/P3870
思路
线段树模板题目
对于区间,我们翻转的时候直接异或
然后开和关就减去相反的就对了
很简单
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#define int long long
using namespace std;
const int maxn=100005;
int a[maxn];
struct tree{
int l,r;
int dat;
int lazy;
}t[maxn<<2];
void pushup(int k)
{
t[k].dat=(t[k<<1].dat+t[k<<1|1].dat);
}
void build(int k,int l,int r)
{
t[k].l=l,t[k].r=r;
if(l==r)
{
t[k].dat=a[l];
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pushup(k);
}
void pushdown(int k)
{
if(t[k].lazy)
{
int len=t[k].r-t[k].l+1;
t[k<<1].dat=(t[k<<1].r-t[k<<1].l+1-t[k<<1].dat);
t[k<<1|1].dat=(t[k<<1|1].r-t[k<<1|1].l+1-t[k<<1|1].dat);
t[k<<1].lazy^=1;
t[k<<1|1].lazy^=1;
t[k].lazy^=1;
}
}
void update(int k,int l,int r)
{
if(l<=t[k].l&&t[k].r<=r)
{
t[k].dat=(t[k].r-t[k].l+1-t[k].dat);
t[k].lazy^=1;
return ;
}
pushdown(k);
int mid=(t[k].l+t[k].r)>>1;
if(l<=mid) update(k<<1,l,r);
if(r>mid) update(k<<1|1,l,r);
pushup(k);
}
int query(int k,int l,int r)
{
if(l<=t[k].l&&t[k].r<=r)
return t[k].dat;
pushdown(k);
int res=0;
int mid=(t[k].l+t[k].r)>>1;
if(l<=mid) res+=query(k<<1,l,r);
if(r>mid) res+=query(k<<1|1,l,r);
return res;
}
int n,m;
signed main()
{
cin>>n>>m;
memset(a,0,sizeof(a));
build(1,1,n);
while(m--)
{
int op,l,r;
cin>>op>>l>>r;
if(op==0)
update(1,l,r);
else if(op==1)
cout<<query(1,l,r)<<'\n';
}
return 0;
}
本博文为wweiyi原创,若想转载请联系作者,qq:2844938982