【解题报告】洛谷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;
}
posted @ 2021-10-19 12:58  wweiyi  阅读(25)  评论(0编辑  收藏  举报
js脚本