• 洛谷 P3870 [TJOI2009]开关


    看题面可以目测得出本题要求对01区间进行区间修改和查询。

    查询区间和,就直接维护区间和。在修改时,就用总灯数(长度)减去当前开着的灯数(当前区间和)作为新的答案。

    考虑修改两次相当于没修改,所以(lazytag)就累计操作数,如果是偶数则不用更新呢,奇数反之。

    其余部分与线段树模板基本相同。

    #include<iostream>
    #define int long long
    using namespace std;
    const int MAXN=100005;
    int n,m,a[MAXN],seg[MAXN<<2],tag[MAXN<<2];
    int u,v,w;
    
    inline void upd(int x)
    {
        seg[x]=seg[x<<1]+seg[x<<1|1];
    }
    
    inline int push_down(int x,int l,int r)
    {
        tag[x<<1]+=tag[x];tag[x<<1|1]+=tag[x];
        int mid=(l+r)>>1;
        if(tag[x]&1)
        {
        	seg[x<<1]=(mid-l+1)-seg[x<<1];
        	seg[x<<1|1]=(r-mid)-seg[x<<1|1];
    	}
        tag[x]=0;
    }
    
    inline int query(int x,int l,int r,int ql,int qr)
    {
        int temp=0,mid=(l+r)>>1;
        if(ql<=l&&r<=qr) return seg[x];
        push_down(x,l,r);
        if(ql<=mid) temp+=query(x<<1,l,mid,ql,qr);
        if(mid<qr) temp+=query(x<<1|1,mid+1,r,ql,qr);
        return temp;
    }
    
    inline void modify(int x,int l,int r,int ql,int qr)
    {
        if(ql<=l&&r<=qr)
        {
            seg[x]=(r-l+1)-seg[x];
            tag[x]+=1;
        } else {
            push_down(x,l,r);
            int mid=(l+r)>>1;
            if(ql<=mid) modify(x<<1,l,mid,ql,qr);
            if(mid<qr) modify(x<<1|1,mid+1,r,ql,qr);
            upd(x);
        }
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>u>>v>>w;
            if(u==0)
                modify(1,1,n,v,w);
            else
                cout<<query(1,1,n,v,w)<<"
    ";
        }
        return 0;
    }
    
  • 相关阅读:
    Alpha冲刺博客集
    Alpha冲刺——第一天
    团队项目需求分析
    结对第二次作业
    项目选题报告
    随笔2 PAT1001.A+B Format (20)
    随笔1 大一下学期自我目标
    大数
    列变位法解密--百度之星B题
    hdu1874 畅通工程续 dijkstra 最短路
  • 原文地址:https://www.cnblogs.com/ehznehc/p/11296852.html
Copyright © 2020-2023  润新知