zoukankan      html  css  js  c++  java
  • P3870 [TJOI2009]开关 线段树 异或

      

    题目描述

    现有N(2 ≤ N ≤ 100000)盏灯排成一排,从左到右依次编号为:1,2,......,N。然后依次执行M(1 ≤ M ≤ 100000)项操作,操作分为两种:第一种操作指定一个区间[a, b],然后改变编号在这个区间内的灯的状态(把开着的灯关上,关着的灯打开),第二种操作是指定一个区间[a, b],要求你输出这个区间内有多少盏灯是打开的。灯在初始时都是关着的。

    输入输出格式

    输入格式:

    第一行有两个整数N和M,分别表示灯的数目和操作的数目。接下来有M行,每行有三个整数,依次为:c, a, b。其中c表示操作的种类,当c的值为0时,表示是第一种操作。当c的值为1时表示是第二种操作。a和b则分别表示了操作区间的左右边界(1 ≤ a ≤ b ≤ N)。

    输出格式:

    每当遇到第二种操作时,输出一行,包含一个整数:此时在查询的区间中打开的灯的数目。

    输入输出样例

    输入样例#1: 复制
    4 5
    0 1 2
    0 2 4
    1 2 3
    0 2 4
    1 1 4
    
    输出样例#1: 复制
    1
    2

    可以用异或 见代码
    因为一开始亮的灯数为0 所以不用build
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    const int N=100000+5;
    ll sum[N<<2],col[N<<2];
    
    void up(int pos)
    {
        sum[pos]=sum[pos<<1]+sum[pos<<1|1];
    }
    void down(int pos,int m)
    {
        if(col[pos])
        {
            col[pos<<1]^=1;//每个下传懒标记进行异或   因为负负得正
            col[pos<<1|1]^=1;
            sum[pos<<1]=(m-(m>>1))-sum[pos<<1];//正常修改
            sum[pos<<1|1]=(m>>1)-sum[pos<<1|1];
            col[pos]=0;
        }
    }
    void update(int L,int R,int l,int r,int pos)
    {
        if(L<=l&&r<=R)
        {
            col[pos]^=1;//不能改成1! 
            sum[pos]=r-l+1-sum[pos];
            return ;
        }
        int m=(l+r)>>1;
        down(pos,r-l+1);
        if(L<=m)
            update(L,R,lson);
        if(R>m)
            update(L,R,rson);
        up(pos);
    }
    int query(int L,int R,int l,int r,int pos)//正常讯问
    {
        if(L<=l&&r<=R)
            return sum[pos];
        down(pos,r-l+1);
        int ans=0;
        int m=(l+r)>>1;
        if(L<=m)ans+=query(L,R,lson);
        if(R>m)ans+=query(L,R,rson);
        return ans;
    }
    
    int main()
    {
        int n,m;
        RII(n,m);
        rep(i,1,m)
        {
            int a,b,c;RIII(a,b,c);
            if(a)
                cout<<query(b,c,1,n,1)<<endl;
            else update(b,c,1,n,1);
        }
        return 0;
    }
    View Code
    
    
  • 相关阅读:
    172. Factorial Trailing Zeroes
    96. Unique Binary Search Trees
    95. Unique Binary Search Trees II
    91. Decode Ways
    LeetCode 328 奇偶链表
    LeetCode 72 编辑距离
    LeetCode 226 翻转二叉树
    LeetCode 79单词搜索
    LeetCode 198 打家劫舍
    LeetCode 504 七进制数
  • 原文地址:https://www.cnblogs.com/bxd123/p/10841336.html
Copyright © 2011-2022 走看看