CodeVs 1690 开关灯
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeVs 1690 开关灯相关的知识,希望对你有一定的参考价值。
线段树区间更新 区间查询~
好久没写过线段树了 写挫了好几次了了了。。
最后瞅了瞅题解才发现自己思路有些问题
#include <cstdio> #include <algorithm> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int n,m; struct data{ int l,r,v; bool lazy; }tr[2000001]; void build(int l,int r,int rt){ tr[rt].l=l; tr[rt].r=r; if(l==r) return; int m =(l+r)>>1; build(lson); build(rson); } void pushdown(int rt){ if(!tr[rt].lazy) return; tr[rt<<1].lazy=!tr[rt<<1].lazy; tr[rt<<1|1].lazy=!tr[rt<<1|1].lazy; tr[rt<<1].v=tr[rt<<1].r-tr[rt<<1].l+1-tr[rt<<1].v; tr[rt<<1|1].v=tr[rt<<1|1].r-tr[rt<<1|1].l+1-tr[rt<<1|1].v; tr[rt].lazy=0; } void update(int x,int y,int rt){ pushdown(rt); int l = tr[rt].l; int r = tr[rt].r; if(l==x && r==y){ tr[rt].v=y-x+1-tr[rt].v; if(l!=r) tr[rt].lazy=1; return; } int m =(l+r)>>1; if(y<=m) update(x,y,rt<<1); else if(m<x) update(x,y,rt<<1|1); else { update(x,m,rt<<1); update(m+1,y,rt<<1|1); } tr[rt].v=tr[rt<<1].v+tr[rt<<1|1].v; } int query(int x,int y,int rt){ pushdown(rt); int l = tr[rt].l;int r =tr[rt].r; if(l==x && r==y) return tr[rt].v; int m = (l+r)>>1; if(m>=y) return query(x,y,rt<<1); else if(m<x) return query(x,y,rt<<1|1); else return (query(x,m,rt<<1)+query(m+1,y,rt<<1|1)); } int main(){ scanf("%d%d",&n,&m); build(1,n,1); for(int i=1;i<=m;i++){ int flag,x,y; scanf("%d%d%d",&flag,&x,&y); if(flag) printf("%d\n",query(x,y,1)); else update(x,y,1); } return 0; }
以上是关于CodeVs 1690 开关灯的主要内容,如果未能解决你的问题,请参考以下文章