Problem DescriptionThis is a very simple question. There are N intervals in number axis, and M queries just like “QUERY(a,b)” indicate asking the maximum number of the disjoint intervals between (a,b) .InputThere are several test cases. For each test case, the first line contains two integers N, M (0<N, M<=100000) as described above. In each following N lines, there are two integers indicate two endpoints of the i-th interval. Then come M lines and each line contains two integers indicating the endpoints of the i-th query.You can assume the left-endpoint is strictly less than the right-endpoint in each given interval and query and all these endpoints are between 0 and 1,000,000,000.OutputFor each query, you need to output the maximum number of the disjoint intervals in the asked interval in one line.Sample Input3 21 22 31 31 21 3Sample Output12AuthorHIT分析:首先不难看出要离散化,因为10^9很明显不好操作,所以考虑离散化。然后考虑贪心排序,把重的大区间都忽略掉,因为它一定是没有作用的,假设有两个重叠区间,我肯定选小的那个(贪心)。接着考虑枚举区间选就行了,但很明显要TLE,于是考虑倍增,f[i][j]表示从i坐标开始向右走2^j个区间的右端点的坐标,于是可以转移:f[i][j]=f[i][f[i][j-1][j-1];注意如果f[i][j-1]已经为最右端了,那f[i][j]也只能是最右端,这里要判断一下,不然f[i][j]就会被赋成0影响结果。最后跑一边倍增加起来就ok了;
# include <iostream>
# include <cstdio>
# include <cstdlib>
# include <cstring>
# include <cmath>
# include <vector>
# include <algorithm>
using namespace std;
inline int read()
{
register int f=1,i=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){i=(i<<3)+(i<<1)+ch-'0';ch=getchar();}
return i*f;
}
vector<int>tmp;
struct node
{
int l,r;
friend bool operator < (const node &a,const node &b)
{
if(a.l==b.l) return a.r<b.r;
return a.l<b.l;
}
}q[100005];
int f[100005][28],size,n,m;
inline void LSH()
{
sort(tmp.begin(),tmp.end());
size=unique(tmp.begin(),tmp.end())-tmp.begin();tmp.resize(size);
for(int i=0;i<n;++i)
{
q[i].l=lower_bound(tmp.begin(),tmp.end(),q[i].l)-tmp.begin();
q[i].r=lower_bound(tmp.begin(),tmp.end(),q[i].r)-tmp.begin();
}
}
inline int solve(int l,int r)
{
int sum=0;
for(int i=25;i>=0;--i)
{
if(f[l][i]<=r)
{
sum+=(1<<i);
l=f[l][i];
}
}return sum;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
tmp.clear();
for(int i=0;i<n;++i)
{
q[i].l=read(),q[i].r=read();
tmp.push_back(q[i].l);
tmp.push_back(q[i].r);
}
LSH();sort(q,q+n);
int R=size,pos=n-1;
for(int i=size-1;i>=0;--i)
{
while(pos>=0&&q[pos].l>=i) R=min(R,q[pos--].r);
f[i][0]=R;//找到最近的右端点
}
for(int j=1;j<=25;++j)
for(int i=0;i<size;++i)
if(f[i][j-1]<size) f[i][j]=f[f[i][j-1]][j-1];
else f[i][j]=size;//特判
int l,r;
while(m--)
{
l=read(),r=read();
l=lower_bound(tmp.begin(),tmp.end(),l)-tmp.begin();
r=upper_bound(tmp.begin(),tmp.end(),r)-tmp.begin()-1;
if(l==size||r<=l||r<0) {puts("0"); continue;}
cout<<solve(l,r)<<endl;
}
}
}