Mayor’s posters
题目链接: Mayor’s posters POJ - 2528
题意
给你n(1 < n < 10000)个海报,每个海报有l和r(1<=l<=r<=1e7),代表自己覆盖的区间,后面的会覆盖前面的,求总共会当最后一个覆盖结束后有多少海报可以看见。
补充,这里的离散化其实有点问题的,例子1-10,1-1,3-10.如果不好的离散会输出2.
经研究最好的离散是在插入l,r两个点的时,把l+1,l-1,r+1,r-1都离散化,这样一定不会出问题。
思路
本题的难点在于修改的l,r区间非常的大,如果直接开数组,暴力跑线段树那么非常容易T,我们又发现了另外一点,就是总共只有1e4个海报,就是只有2e4个有效点,另外的都无所谓,所以先把数据存起来离线即可。
代码
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cstdio>
#include <string>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <sstream>
#include <memory>
#include <iostream>
#include <algorithm>
using namespace std;
#define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
#define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
#define debug(x) cerr<<#x<<" = "<<(x)<<endl
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
typedef double db;
typedef long long ll;
const int MAXN = (int)2e4+7;
const int INF = (int)0x3f3f3f3f;
inline int read() { int c = 0, f = 1;char ch = getchar();
while (ch < '0' || ch > '9') {if (ch == '-') f = -1;ch = getchar();}
while (ch >= '0' && ch <= '9') {c = c * 10 + ch - '0';ch = getchar();}
return c * f;
}
#define lson rt<<1
#define rson rt<<1|1
int A[MAXN],N;
int tot = 0;
struct tre{
int sum;
int add;
}tree[MAXN<<2];
void PushDown(int rt,int ln,int rn){
if (tree[rt].add){
tree[lson].sum = tree[rt].add;
tree[rson].sum = tree[rt].add;
tree[lson].add = tree[rt].add;
tree[rson].add = tree[rt].add;
tree[rt].add = 0;
}
}
void Update(int L,int R,int C,int l,int r,int rt){
if (L <= l && r <= R){
tree[rt].sum = C;
tree[rt].add = C;
return ;
}
int m = (l+r)>>1;
PushDown(rt,m+1-l,r-m);
if (L <= m) Update(L,R,C,l,m,lson);
if (R > m) Update(L,R,C,m+1,r,rson);
}
void Down(int l,int r,int rt) {
if (l == r) {
A[l] = tree[rt].sum;
return;
}
PushDown(rt,1,1);
int m = l+r>>1;
Down(l,m,lson);
Down(m+1,r,rson);
}
set<int>se;
vector<int> vp;
int getID(int x) {return lower_bound(vp.begin(),vp.end(),x)-vp.begin()+1; }
struct Node {
int l,r;
Node(int l = 0,int r = 0):l(l),r(r){}
}qst[MAXN];
int main()
{
int T;
scanf("%d",&T);
while (T --) {
int M = read(); N = 2e4;
tot = 0;mmm(tree,0);se.clear();vp.clear();
rep(i,1,M) {
int l = read(),r = read();
qst[i] = Node(l,r);
vp.pb(l),vp.pb(r);
}
sort(vp.begin(),vp.end());vp.erase(unique(vp.begin(),vp.end()),vp.end());
rep(i,1,M) {
int l = getID(qst[i].l);
int r = getID(qst[i].r);
Update(l,r,++tot,1,N,1);
}
Down(1,N,1);
rep(i,1,N) {
if (se.count(A[i]) == 0)se.insert(A[i]);
}
se.erase(0);
printf("%d\n",se.size());
mmm(tree,0);tot = 0;se.clear();
}
}