Light bulbs (树状数组模板题)

There are N light bulbs indexed from 00 to N−1. Initially, all of them are off.

A FLIP operation switches the state of a contiguous subset of bulbs. FLIP(L, R)means to flip all bulbs x such that L≤x≤R. So for example, FLIP(3, 5) means to flip bulbs 3 , 4 and 5, and FLIP(5, 5)means to flip bulb 5.

Given the value of N and a sequence of M flips, count the number of light bulbs that will be on at the end state.

InputFile

The first line of the input gives the number of test cases, T. T test cases follow. Each test case starts with a line containing two integers N and M, the number of light bulbs and the number of operations, respectively. Then, there are M more lines, the i-th of which contains the two integers Li? and Ri?, indicating that the ii-th operation would like to flip all the bulbs from Li? to Ri? , inclusive.

1≤T≤1000

1 ≤N≤1000000

1 ≤M≤1000

0≤Li?≤Ri?≤N−1

OutputFile

For each test case, output one line containing Case #x: y, where xx is the test case number (starting from 11) and yyis the number of light bulbs that will be on at the end state, as described above.

样例输入复制

2
10 2
2 6
4 8
6 3
1 1
2 3
3 4

样例输出复制

Case #1: 4
Case #2: 3
#include <bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
const int maxn=2e3+5;
int str[maxn],str2[maxn],c[1000005],n,m;
int ask(int x)
{
    int ans=0;
    for(; x; x-=x&-x)ans+=c[x];
    return ans;
}
void add(int x,int y)
{
    for(; x<=n; x+=x&-x)c[x]+=y;
}
template<class T>
inline void read(T&x)
{
    T ans=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘)
    {
        if(ch==‘-‘)f=-1;
        ch=getchar();
    }
    while(ch>=‘0‘&&ch<=‘9‘)
    {
        ans=ans*10+ch-‘0‘;
        ch=getchar();
    }
    x=ans*f;
}
int main()
{
    int t,l,r,cnt=0,k=0;
    read(t);
    while(t--)
    {
        cnt=0;
        read(n);
        read(m);
        int m2=m;
        while(m2--)
        {
            read(l);read(r);
            ++l,++r;
            add(l,1);
            add(r+1,-1);
            str[++cnt]=l,str2[cnt]=l;
            str[++cnt]=r+1,str2[cnt]=r+1;
        }
        sort(str+1,str+cnt+1);
        int cnt2=0;
        for(int i=1; i<=cnt; ++i)
        {
            if(str[i]!=str[cnt2])
                str[++cnt2]=str[i];
        }
        int ans=0,flag;
        for(int i=1; i<cnt2; ++i)
        {
            flag=ask(str[i]);
            if((flag&1)==1)
                ans+=str[i+1]-1-str[i]+1;
        }
        printf("Case #%d: %d\n",++k,ans);
        for(int i=1; i<=2*m; i+=2)
        {
            add(str2[i],-1);
            add(str2[i+1],1);
        }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/lengsong/p/11523654.html

时间: 2024-10-06 08:13:16

Light bulbs (树状数组模板题)的相关文章

POJ 3928 Ping pong 树状数组模板题

开始用瓜神说的方法撸了一发线段树,早上没事闲的看了一下树状数组的方法,于是又写了一发树状数组 树状数组: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #includ

树状数组模板题(特强浓雾

#include<bits/stdc++.h> using namespace std; int a,b; int c[100005]; void add(int x,int y)//树状数组初始化 { while(x<=a+b) c[x]+=y,x+=x&-x;//露馅了噗哈哈哈哈哈哈蛤哈哈哈哈哈哈 } int ask(int x)//询问 { int ans=0; while(x) ans+=c[x],x-=x&-x; return ans; } int main()

树状数组模板题 P1904

Description 给定一个长度为n的整数数组A[1].A[2].-.A[n](-10^9 Input 第一行包含两个整数n和m,表示数组有n个元素,m表示有m个操作:接下来的一行包含n个整数,第i个整数表示A[i]:再接下来的m行,每行表示一个操作. Output 按输入顺序输出操作2的结果. Hint 反正要用long long Solution 嗯,这个题,告诉我们,位运算要打括号... #include<cstdio> #include<cstring> #includ

hdu 1541 Stars 树状数组模板题

#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int  maxn=15010; const int maxlen=32010; int tree[4*maxn]; int lowbit(int n) { return (n&-n); } int getsum(int i) { int sum=0; while(i>0) { sum+=tree

HDU-1754 I Hate It (树状数组模板题——单点更新,区间查询最大值)

题目链接 ac代码(注意字符读入前需要注意回车的影响) #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<bitset> #include<cassert> #include<cctype> #include<cmath> #include<cstdlib> #include<c

二维树状数组模板(区间修改+区间查询)

二维树状数组模板(区间修改+区间查询) 例题:JOIOI上帝造题的七分钟 一共两种操作: \(L\ x_1\ y_1\ x_2\ y_2\ d\):把\((x_1,y_1)\),\((x_2,y_2)\)这个矩形内所有元素加\(d\). \(k\ x_1\ y_1\ x_2\ y_2\):查询\((x_1,y_1)\),\((x_2,y_2)\)这个矩形内所有元素的和. 代码如下: #include<bits/stdc++.h> #define RG register #define IL i

hdu 3584 二进制0,1反转 三维树状数组 及三维树状数组模板

先贴自己类比二维树状数组写的三维树状数组模板: 开始的时候循环体内j=y,k=z,没写,以为自己思路错了,,,hehe..... 更高维的树状数组以此类比 const int MAXN = 100+10; int c[MAXN][MAXN][MAXN];int X,Y,Z; int N; inline int lowbit(int x){return x&(-x);} void update(int x, int y, int z, int v) { int i=x,j=y,k=z; while

poj 1195 二维树状数组 及二维树状数组模板

http://poj.org/problem?id=1195 求矩阵和的时候,下标弄错WA了一次... 求矩形(x1,y1) (x2,y2)的sum |sum=sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1) 二维树状数组讲解:http://blog.csdn.net/u011026968/article/details/38532117 二维树状数组模板: /*========================================

HDU1166 敌兵布阵 树状数组水题

中文题目,很简单的题目,区间求和,当然对于线段树来说也很水,为了练习一下树状数组,多做做水题吧,加深理解,并且打好基础,我算是被没打好基础给吓坏了,宁可多花几个小时 刷刷水题扎实点, 很裸的题目 操作也很裸,了解树状数组的肯定能做 #include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string&g