(2019hdu多校第十场) Welcome Party
Welcome Party
时间限制: 4 Sec 内存限制: 128 MB题目描述
The annual welcome party of the Department of Computer Science and Technology is coming soon! Many students have been applying to show up at the welcome party, and every one of them can choose to sing a song or play crosstalk. This troubles the chief director a lot: how to arrange the program list, such that every student can have a chance to show up on the stage, and the satisfactory value of audiences is maximized?
To cope with this problem, the director proposes a model. In this model, every student has two attributes: the singing ability and crosstalking ability. The satisfactory value of audiences to singings is the maximum singing ability among all students that choose to sing a song; similarly, the satisfactory value to crosstalks is the maximum crosstalking ability among all students that choose play crosstalk. The strange thing is, the overall satisfactory value to the whole party is negatively related to the absolute difference between the satisfactory values to singings and crosstalks. The problem is, what is the minimum possible absolute difference between the satisfactory values of the two types of programs?
Note that:
- every student should choose exactly one type of programs to play;
- at least one student should sing a song, and at least one student should play crosstalk.
To cope with this problem, the director proposes a model. In this model, every student has two attributes: the singing ability and crosstalking ability. The satisfactory value of audiences to singings is the maximum singing ability among all students that choose to sing a song; similarly, the satisfactory value to crosstalks is the maximum crosstalking ability among all students that choose play crosstalk. The strange thing is, the overall satisfactory value to the whole party is negatively related to the absolute difference between the satisfactory values to singings and crosstalks. The problem is, what is the minimum possible absolute difference between the satisfactory values of the two types of programs?
Note that:
- every student should choose exactly one type of programs to play;
- at least one student should sing a song, and at least one student should play crosstalk.
输入
The first line of input consists of a single integer T (1≤T≤70), the number of test cases.
Each test case starts with a line of a single integer n (2≤n≤100000), denoting the number of students applying to show up on the stage. Then follow n lines, each containing two integers x and y (0≤x,y≤1018), denoting the singing ability and crosstalking ability of a student.
It is guaranteed that the sum of n over all test cases never exceeds 1000000.
Each test case starts with a line of a single integer n (2≤n≤100000), denoting the number of students applying to show up on the stage. Then follow n lines, each containing two integers x and y (0≤x,y≤1018), denoting the singing ability and crosstalking ability of a student.
It is guaranteed that the sum of n over all test cases never exceeds 1000000.
输出
For each test case, output a single integer, denoting the minimum possible absolute difference between the satisfactory values of the two types of programs.
样例输入
2
5
27 46
89 13
55 8
71 86
22 35
3
3 5
4 7
6 2
样例输出
3
1
方法:
题目要求唱歌的和说相声中能力最强的差值最小
首先按唱歌能力从高到低排序,枚举第i个人是唱歌能力最强的人,那么i前面的所有人必然都要去说相声,
然后在i后面找到一个说相声能力与i的唱歌能力最接近的。取前者和后者的最大值作为说相声的最高能力,最后更新答案。
由于i之后的数使无序的,所以考虑了二分加主席树求这个值。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e5+5;
int node_cnt=0,p,q;
ll b[N];
struct data
{
ll x,y;
}a[N];
int lc[N<<5],rc[N<<5],rt[N<<5];
ll sum[N<<5];
inline void build(int &k,int l,int r){
k=node_cnt++;
if(l==r) return;
int mid=(l+r)/2;
build(lc[k],l,mid);
build(rc[k],mid+1,r);
}
inline int modify(int k,int l,int r){
int oo=++node_cnt;
lc[oo]=lc[k];rc[oo]=rc[k];sum[oo]=sum[k]+1;
if(l==r) return oo;
int mid=(l+r)/2;
if(p<=mid) lc[oo]=modify(lc[oo],l,mid);
else rc[oo]=modify(rc[oo],mid+1,r);
return oo;
}
inline int query(int u,int v,int l,int r,int k){
int mid=(l+r)/2;
int cnt=sum[lc[v]]-sum[lc[u]],ans;
if(l==r) return l;
if(cnt>=k) ans=query(lc[u],lc[v],l,mid,k);
else ans=query(rc[u],rc[v],mid+1,r,k-cnt);
return ans;
}
bool cmp(data a,data b)
{
return a.x>b.x;
}
int _,n;
int main()
{
scanf("%d",&_);
while(_--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&a[i].x,&a[i].y);
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)
{
b[i]=a[i].y;
}
ll ans=0x3f3f3f3f3f3f3f3f;
node_cnt=p=q=0;
memset(sum,0,sizeof sum);
sort(b+1,b+n+1);
q=unique(b+1,b+n+1)-b-1;
build(rt[0],1,q);
for(register int i=1;i<=n;i++){
p=lower_bound(b+1,b+q+1,a[i].y)-b;
rt[i]=modify(rt[i-1],1,q);
}
ll tmp=0,fff=0;
for(int i=1;i<=n;i++)
{
int l=1,r=n-i;
while(l<r)
{
int mid=(l+r)/2;
if(b[query(rt[i], rt[n], 1, q, mid)]>=a[i].x) r=mid;
else l=mid+1;
}
for(int j=l-2;j<=l+2;j++)
{
if(j<1||j>n-i) continue;
ans=min(ans,abs(a[i].x-max(tmp,b[query(rt[i], rt[n], 1, q, j)])));
}
if(fff) ans=min(ans,abs(a[i].x-tmp));
tmp=max(tmp,a[i].y);
fff=1;
}
printf("%lld\n",ans);
}
return 0;
}