n(n<=10000)個人依次貼海報,給出每張海報所貼的範圍li,ri (1<=li<=ri<=1e7) 。求出最後還能看見多少張海報。
Input
第一行: 樣例個數T
第二行: 貼海報的人n
第三行: 每個人貼海報的範圍
接下來n行: 每個人貼海報的範圍
Output
對於每一個輸入,輸出最後可以看到的海報張數。下面這個圖是樣例解釋
Sample Input
1
5
1 4
2 6
8 10
3 4
7 10
Sample Output
4
海報張貼的範圍是1e7直接線段樹是肯定要超時的更別說還多個樣例了,但是海報的張數才1e4,所以總的範圍內有非常多點是沒有用到的,可以把這些點全部省略只保留用到的端點,然後在線段樹就方便許多了,然後還有一個問題
先來個樣例吧
2
1 5
1 2
4 5
正確答案應該是3,但是直離散化端點後之後求得的是2,在點2和4之間應該還有一段但是離散化端點之後這一段就被省略了,所以我們需要把省略的這一把分再加入離散化裏面,只用加一個省略線段之間的任意一點就可以了(如果省略部分長度大於1),這樣就能ac啦,這道題數據有點水,不加省略的部分也能ac。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e4+10;
int n,t,a[N],l[N],r[N],idx;
vector<int> ve;
struct node
{
int l,r;
int id;//表示將整個區間覆蓋的報紙編號,0表示不存在完全覆蓋
}tr[N<<4];
void pushdown(int rt)//只保存能完全覆蓋的最小區間,就不用pushup了
{
if(tr[rt].id)
{
tr[rt<<1|1].id=tr[rt<<1].id=tr[rt].id;
tr[rt].id=0;//記得清空
}
}
void build(int rt,int l,int r)
{
if(l==r) tr[rt]={l,l,0};
else
{
tr[rt]={l,r};
int mid=l+r>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
}
}
void updata(int rt,int l,int r,int d)
{
if(l<=tr[rt].l&&tr[rt].r<=r)
{
tr[rt].id=d;
}
else
{
pushdown(rt);
int mid =tr[rt].l+tr[rt].r>>1;
if(l<=mid) updata(rt<<1,l,r,d);
if(r>mid) updata(rt<<1|1,l,r,d);
}
}
int ans;
bool st[N];
void query(int rt,int l,int r)
{
if(tr[rt].id)
{
if(!st[tr[rt].id])
{
ans++;
st[tr[rt].id]=1;
}
return ;
}
if(tr[rt].l==tr[rt].r) return ;//記得及時結束
pushdown(rt);
int mid=tr[rt].l+tr[rt].r>>1;
if(l<=mid) query(rt<<1,l,r);
if(r>mid) query(rt<<1|1,l,r);
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
ve.clear();
for(int i=1;i<=n;i++)
{
scanf("%d%d",l+i,r+i);
ve.push_back(l[i]);
ve.push_back(r[i]);
}
sort(ve.begin(),ve.end());
ve.erase(unique(ve.begin(),ve.end()),ve.end());//去重
int sz=ve.size();//一定要加這一步,因爲後面遍歷的途中ve.size()就在變化,會一直向裏面再加多餘的點直到MLE
for(int i=1;i<sz;i++)
if(ve[i]-ve[i-1]>1) ve.push_back((ve[i]-1));
sort(ve.begin(),ve.end());
build(1,1,ve.size());
for(int i=1;i<=n;i++)
{
int x=lower_bound(ve.begin(),ve.end(),l[i])-ve.begin()+1;//我想要端點從1開始
int y=lower_bound(ve.begin(),ve.end(),r[i])-ve.begin()+1;
updata(1,x,y,i);
}
ans=0;
memset(st,0,sizeof st);
query(1,1,ve.size());
printf("%d\n",ans);
}
return 0;
}