【codevs1690】开关灯【线段树】

题目描述 Description

YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人陆续按下开关,这些开关可以改变从第i盏灯到第j盏灯的状态,现在YYX想知道,从第x盏灯到第y盏灯中有多少是亮着的(1<=i,j,x,y<=N)

输入描述 Input Description

第 1 行: 用空格隔开的两个整数N和M

第 2..M+1 行: 每行表示一个操作, 有三个用空格分开的整数: 指令号(0代表按下开关,1代表询问状态), x 和 y

输出描述 Output Description

第 1..询问总次数 行:对于每一次询问,输出询问的结果

样例输入 Sample Input

4 5

0 1 2

0 2 4

1 2 3

0 2 4

1 1 4

样例输出 Sample Output

1

2

数据范围及提示 Data Size & Hint

一共4盏灯,5个操作,下面是每次操作的状态(X代表关上的,O代表开着的):

XXXX -> OOXX -> OXOO -> 询问1~3 -> OOXX -> 询问1~4

题解:

区间取反和区间查询。灯亮用1表示,灯灭用0表示

线段树保存区间和。

一个区间取反后亮着灯的个数实际上是r-l+1-t[x];

我们在下放标记时只需要lazy[x]=!lazy[x]。

代码:

#include<iostream>
#include<cstdio>
using namespace std;
int t[1000001],n,m,kind,x,y,lazy[1000001];
void paint(int k,int l,int r)
{
    t[k]=r-l+1-t[k];
    lazy[k]=!lazy[k];
}
void pushdown(int k,int l,int r)
{
    int mid;
    mid=(l+r)/2;
    paint(k*2,l,mid);
    paint(k*2+1,mid+1,r);
    lazy[k]=0;
}
void insert(int k,int l,int r,int ll,int rr)
{
    int mid;
    if (ll<=l&&r<=rr)
     {
        paint(k,l,r);
        return;
     }
     mid=(l+r)/2;
     if (lazy[k]==1) pushdown(k,l,r);
     if (ll<=mid) insert(k*2,l,mid,ll,rr);
     if (mid<rr) insert(k*2+1,mid+1,r,ll,rr);
     t[k]=t[2*k]+t[2*k+1];
}
int qsum(int k,int l,int r,int ll,int rr)
{
    int mid,ans(0);
    if  (ll<=l&&r<=rr) return t[k];
    mid=(l+r)/2;
    if (lazy[k]==1) pushdown(k,l,r);
    if (ll<=mid) ans+=qsum(k*2,l,mid,ll,rr);
    if (mid<rr) ans+=qsum(k*2+1,mid+1,r,ll,rr);
    return ans;
}
int main()
{
    cin>>n>>m;
    for (int i=1;i<=m;i++)
      {
          scanf("%d%d%d",&kind,&x,&y);
          if (kind==0) insert(1,1,n,x,y);
          if (kind==1) printf("%d\n",qsum(1,1,n,x,y));
      }
}
时间: 2024-10-31 14:35:29

【codevs1690】开关灯【线段树】的相关文章

CODEVS1690|开关灯|线段树(带lazy)

题目描述 Description    YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人陆续按下开关,这些开关可以改变从第i盏灯到第j盏灯的状态,现在YYX想知道,从第x盏灯到第y盏灯中有多少是亮着的(1<=i,j,x,y<=N)输入描述 Input Description第 1 行: 用空格隔开的两个整数N和M第 2..M+1 行: 每行表示一个操作, 有三个用空格分开的整数

BZOJ 1230: [Usaco2008 Nov]lites 开关灯( 线段树 )

线段树.. --------------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; ++i ) #define clr( x

codevs 1690 开关灯 线段树+延迟标记

1690 开关灯 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人陆续按下开关,这些开关可以改变从第i盏灯到第j盏灯的状态,现在YYX想知道,从第x盏灯到第y盏灯中有多少是亮着的(1<=i,j,x,y<=N) 输入描述 Input Description 第 1 行: 用空格隔开的两个整数N和

BZOJ 1230--lites 开关灯(线段树)

1230: [Usaco2008 Nov]lites 开关灯 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1682  Solved: 876[Submit][Status][Discuss] Description Farmer John尝试通过和奶牛们玩益智玩具来保持他的奶牛们思维敏捷. 其中一个大型玩具是牛栏中的灯. N (2 <= N <= 100,000) 头奶牛中的每一头被连续的编号为1..N, 站在一个彩色的灯下面.刚到傍晚的时候

B1230 [Usaco2008 Nov]lites 开关灯 线段树

就是线段树维护异或和.之前我线段树区间修改down都是修改当前区间,结果debug出不来,改成每次向下了. 题干: Description Farmer John尝试通过和奶牛们玩益智玩具来保持他的奶牛们思维敏捷. 其中一个大型玩具是牛栏中的灯. N (2 <= N <= 100,000) 头奶牛中的每一头被连续的编号为1..N, 站在一个彩色的灯下面.刚到傍晚的时候, 所有的灯都是关闭的. 奶牛们通过N个按钮来控制灯的开关; 按第i个按钮可以改变第i个灯的状态.奶牛们执行M (1 <=

【codevs1690】开关灯 线段树 区间修改+区间求和(标记)

[codevs1690]开关灯 2014年2月15日4930 题目描述 Description YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人陆续按下开关,这些开关可以改变从第i盏灯到第j盏灯的状态,现在YYX想知道,从第x盏灯到第y盏灯中有多少是亮着的(1<=i,j,x,y<=N) 输入描述 Input Description 第 1 行: 用空格隔开的两个整数N和M 第

【BZOJ1230】 [Usaco2008 Nov]lites 开关灯 线段树

递归不要加inline 会出现神奇的错误..... 1 #include <iostream> 2 #include <cstdio> 3 #define N 100010 4 using namespace std; 5 struct Tree 6 { 7 int size,rev,l,r; 8 }seg[N*4]; 9 int n,m; 10 inline int read() 11 { 12 char c; 13 int ans=0,f=1; 14 while (!isdig

Codevs_1690_开关灯(线段树)

描述 http://codevs.cn/problem/1690/ 一排共 n 个灯,起初都是关着的,现在有 m 次操作. 0 开头的操作代表将 l ~ r 的开关按一遍,1 开头的操作代表询问 l ~ r 共多少个开着的灯. 分析 刚开始想的是用 0 , 1 , -1 分别代表区间都是关着的,都是开着的,有开的又有关的,跟新和查询的时候都是查找到非 -1 的区间再做处理,但是 TLE 了. 想一下如果灯是 1 0 1 0 1 0 1 0 1...这样排列的,那就退化得不成样子了. 所以用 on

线段树--codevs 1690 开关灯

codevs 1690 开关灯 USACO 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人陆续按下开关,这些开关可以改变从第i盏灯到第j盏灯的状态,现在YYX想知道,从第x盏灯到第y盏灯中有多少是亮着的(1<=i,j,x,y<=N) 输入描述 Input