首页 > 代码库 > 【USACO 2008 Nov Gold】 3.Light Switching(lites 开关灯) 区间修改线段树
【USACO 2008 Nov Gold】 3.Light Switching(lites 开关灯) 区间修改线段树
题意:
n、m,n个灯,m次操作
两种操作 0: 这段区间全部状态取反,初始全部为0
1: 询问这段区间有几个灯是亮的。
裸线段树,弱爆了。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 101000 #define inf 0x3f3f3f3f using namespace std; struct Segment_Tree { int l,r,x; bool flag; }s[N<<2]; int n,m; void pushup(int x){s[x].x=s[x<<1].x+s[x<<1|1].x;} void pushdown(int x) { if(s[x].flag) { s[x].flag=0; if(s[x].l<s[x].r) { s[x<<1].flag^=1; s[x<<1|1].flag^=1; } s[x].x=s[x].r-s[x].l+1-s[x].x; } } void build(int note,int l,int r) { s[note].l=l; s[note].r=r; if(l==r)return ; int mid=l+r>>1; build(note<<1,l,mid); build(note<<1|1,mid+1,r); } void add(int note,int l,int r) { if(s[note].l==l&&s[note].r==r) { s[note].flag^=1; pushdown(note); return ; } pushdown(note); int mid=s[note].l+s[note].r>>1; if(r<=mid)add(note<<1,l,r),pushdown(note<<1|1); else if(l>mid)add(note<<1|1,l,r),pushdown(note<<1); else add(note<<1,l,mid),add(note<<1|1,mid+1,r); pushup(note); } int query(int note,int l,int r) { pushdown(note); if(s[note].l==l&&r==s[note].r)return s[note].x; int mid=s[note].l+s[note].r>>1; if(r<=mid)return query(note<<1,l,r); else if(l>mid)return query(note<<1|1,l,r); else return query(note<<1,l,mid)+query(note<<1|1,mid+1,r); } int main() { int i,j,k; int a,b,c; scanf("%d%d",&n,&m); build(1,1,n); while(m--) { scanf("%d%d%d",&a,&b,&c); if(a==0)add(1,b,c); else printf("%d\n",query(1,b,c)); } return 0; }
复制去Google翻译翻译结果
【USACO 2008 Nov Gold】 3.Light Switching(lites 开关灯) 区间修改线段树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。