bzoj 5168:[HAOI2014]貼海報 題解

5168: [HAOI2014]貼海報
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

Sample Output

4

題解:分塊加暴力,中間用一個數組直接覆蓋,兩端暴力枚舉即可。

#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
int N,M,bl,Ans,p[10000005],All[3170];
bool vis[1005];
void fk(int x,int y,int z){
    int Bx=(x-1)/bl+1,By=(y-1)/bl+1;
    if (Bx==By){ //特判,在同一塊
        for (int i=x;i<=y;i++) p[i]=z;
        for (int i=(Bx-1)*bl+1;i<x;i++) if (All[Bx]) p[i]=All[Bx];
        for (int i=y+1;i<=By*bl;i++) if (All[By]) p[i]=All[By];
        All[Bx]=0;return ;
    }
    for (int i=Bx+1;i<By;i++) All[i]=z;
    for (int i=x;i<=Bx*bl;i++) p[i]=z;
    for (int i=(Bx-1)*bl+1;i<x;i++) if (All[Bx]) p[i]=All[Bx];
    for (int i=(By-1)*bl+1;i<=y;i++) p[i]=z;
    for (int i=y+1;i<=By*bl;i++) if (All[By]) p[i]=All[By];
    All[Bx]=All[By]=0;
}
int main()
{
    scanf("%d%d",&N,&M);
    bl=sqrt(N); 
    for (int i=1;i<=M;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        fk(x,y,i);
    }
    vis[0]=1;
    for (int i=1;i<=(N-1)/bl+1;i++){
        if (!All[i]){for (int j=(i-1)*bl+1;j<=min(N,bl*i);j++) if (!vis[p[j]]) Ans++,vis[p[j]]=1;}
        else if (!vis[All[i]]) Ans++,vis[All[i]]=1;
    }
    printf("%d\n",Ans);
    return 0;
} 

PS:雙倍經驗

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章