题解 P1840 【Color the Axis_NOI导刊2011提高(05)】
遇事不决先分块
我用分块水这道题
这道题很裸,但用线段树来做就有点大材小用了,分块可以说是短小精悍,并且可以维护很多数据,真是居家陆行必备的良器啊
不懂分块 点我领取例题
希望你在分块路上越走越远~ 代码如下:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#define N 300500
using namespace std;
inline int read() {
int x = 0,f = 1; char s = getchar();
while(s < '0' || s > '9') {if(s == '-') f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
return x * f;
}
int n,m;
int a[N];
int L[N],R[N],tag[N];
int sum[N],lz[N];
inline void Change(int l,int r) {
if(tag[l] == tag[r]) {
for(int i = l;i <= r;i ++)
if(a[i]) a[i] = 0,sum[tag[i]] --;
return ;
}
for(int i = l;i <= R[tag[l]];i ++)
if(a[i]) a[i] = 0,sum[tag[l]] --;
for(int i = tag[l] + 1;i < tag[r];i ++) lz[i] = 1;
for(int i = L[tag[r]];i <= r;i ++)
if(a[i]) a[i] = 0,sum[tag[r]] --;
}
inline int Qurry() {
int res = 0;
for(int i = 1;i <= tag[n];i ++)
if(!lz[i] && sum[i] > 0)
res += sum[i];
return res;
}
int main() {
n = read(),m = read();
int len = sqrt(n);
for(int i = 1;i <= n;i ++)
tag[i] = (i - 1) / len + 1,a[i] = 1;
for(int i = 1;i <= tag[n];i ++)
L[i] = R[i - 1] + 1,R[i] = min(n,L[i] + len - 1);
for(int i = 1;i <= tag[n];i ++)
sum[i] = R[i] - L[i] + 1;
for(int i = 1;i <= m;i ++) {
int l = read(),r = read();
Change(l,r);
printf("%d\n",Qurry());
}
return 0;
}