1230: [Usaco2008 Nov]lites 开关灯

来源:互联网 发布:js自动轮播代码 编辑:程序博客网 时间:2024/05/16 19:10

题目链接

题目大意:维护01序列,支持区间亦或,求区间和

题解:线段树+标记就好了

我的收获:……

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std; #define M 100005#define ls x<<1#define rs x<<1|1#define lson l,m,x<<1#define rson m+1,r,x<<1|1#define root 1,n,1 int n,m,sum[M<<2],rev[M<<2]; inline void pushup(int x){sum[x]=sum[ls]+sum[rs];} void pushdown(int x,int m){    if(!rev[x]) return ;    rev[ls]^=1,rev[rs]^=1;    sum[ls]=(m-(m>>1))-sum[ls];//区间长度-原值    sum[rs]=(m>>1)-sum[rs];    rev[x]=0;} void build(int l,int r,int x){    rev[x]=0;    if(l==r){sum[x]=0;return ;}    int m=(l+r)>>1;    build(lson);build(rson);    pushup(x);} void updata(int L,int R,int l,int r,int x){    if(L<=l&&r<=R){rev[x]^=1,sum[x]=(r-l+1)-sum[x];return ;}    pushdown(x,r-l+1);    int m=(l+r)>>1;    if(L<=m) updata(L,R,lson);    if(R>m) updata(L,R,rson);    pushup(x);} int query(int L,int R,int l,int r,int x){    if(L<=l&&r<=R) return sum[x];    pushdown(x,r-l+1);    int m=(l+r)>>1,ans=0;    if(L<=m) ans+=query(L,R,lson);    if(R>m) ans+=query(L,R,rson);    return ans;} void work(){    int opt,l,r;    while(m--)    {        scanf("%d%d%d",&opt,&l,&r);        if(opt==0) updata(l,r,root);        if(opt==1) printf("%d\n",query(l,r,root));    }} void init(){    cin>>n>>m;    build(root);} int main(){    init();    work();    return 0;}
原创粉丝点击