5168: [HAOI2014]贴海报
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 89 Solved: 29
[Submit][Status][Discuss]
Description
Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论。为了统一管理,城市委
员 会为选民准备了一个张贴海报的electoral墙。张贴规则如下:
1.electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子;
2.所有张贴的海报的高度必须与electoral墙的高度一致的;
3.每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报;
4.后贴的海报可以覆盖前面已贴的海报或部分海报。
现在请你判断,张贴完所有海报后,在electoral墙上还可以看见多少张海报。
Input
第一行: N M 分别表示electoral墙的长度和海报个数
接下来M行: Ai Bi 表示每张海报张贴的位置
Output
输出贴完所有海报后,在electoral墙上还可以看见的海报数。
1 0<= N <= 10000000 1<=M<=1000 1<= Ai <= Bi <=10000000
所有的数据都是整数。数据之间有一个空格
Sample Input
100 5
1 4
2 6
8 10
3 4
7 10
1 4
2 6
8 10
3 4
7 10
Sample Output
4
一眼线段树 之后发现开不下
m就1000 果断分块啊...
再有就是可以把端点离散化 再在每两个点中间插一个 之后每次暴力就好
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=10*x+ch-'0';ch=getchar();}
return x*f;
}
void print(int x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}
const int N=10001000,M=1010;
int n,block;
int c[N],bel[N],col[10000];
inline void color(int l,int r,int x)
{
register int i,tmp;
if(bel[l]==bel[r])
{
tmp=col[bel[l]];
if(l==(bel[l]-1)*block+1 && r==bel[l]*block)
{col[bel[l]]=x;return ;}
if(tmp)
{
col[bel[l]]=0;
for(i=(bel[l]-1)*block+1;i<=min(bel[l]*block,n);++i) c[i]=tmp;
}
for(i=l;i<=r;++i) c[i]=x;
return ;
}
for(i=bel[l]+1;i<=bel[r]-1;++i) col[i]=x;
if(l==(bel[l]-1)*block+1)
col[bel[l]]=x;
else
{
if(col[bel[l]])
{
tmp=col[bel[l]];col[bel[l]]=0;
for(i=(bel[l]-1)*block+1;i<l;++i) c[i]=tmp;
}
for(i=l;i<=min(bel[l]*block,n);++i) c[i]=x;
}
if(r==bel[r]*block)
col[bel[r]]=x;
else
{
if(col[bel[r]])
{
tmp=col[bel[r]];col[bel[r]]=0;
for(i=r+1;i<=min(bel[r]*block,n);++i) c[i]=tmp;
}
for(i=(bel[r]-1)*block+1;i<=r;++i) c[i]=x;
}
}
bool book[M];
int main()
{
register int i,j,l,r;
n=read();int m=read();
block=ceil(sqrt(n));
for(i=1,j=1;i<=n;++i,++j)
{
bel[i]=bel[i-1]+(j==1);
if(j==block) j=0;
}
for(i=1;i<=m;++i)
{
l=read();r=read();
color(l,r,i);
}
int ans(0);
register int now(1);
while(now<=n)
{
if(col[bel[now]])
{
if(!book[col[bel[now]]]) ans++;
book[col[bel[now]]]=1;
now=bel[now]*block+1;
continue;
}
if(!book[c[now]] && c[now]) ans++;
book[c[now]]=1;
now++;
}
cout<<ans<<endl;
return 0;
}