https://codeforces.com/contest/1472/problem/E
首先我们把第一维都变成较长边,第二维为较短边,然后按第一维排序
然后维护一个第一维递增但较短边下降的序列,因为如果较长边也较小,较短边也较小,那肯定前面的好
然后对于每个矩形就看有没有第一维小于它的,第二维也小于他的,那么直接维护个前缀最小值就行了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
const int inf=2e9;
int n,m,k,cnt,tot,cas;
struct p
{
int h,w,id;
}a[maxl],mi[maxl];
int num[maxl],ans[maxl];
bool vis[maxl];
char s[maxl];
inline int id(int x)
{
return lower_bound(num+1,num+1+tot,x)-num;
}
inline bool cmp(const p&a,const p&b)
{
if(a.h==b.h)
return a.w<b.w;
return a.h<b.h;
}
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].h,&a[i].w);
a[i].id=i;
if(a[i].h<a[i].w)
swap(a[i].h,a[i].w);
num[i]=a[i].h;
}
sort(a+1,a+1+n,cmp);
sort(num+1,num+1+n);
tot=unique(num+1,num+1+n)-num-1;
for(int i=0;i<=tot;i++)
mi[i]=p{0,inf,-1};
for(int i=1;i<=n;i++)
{
int d=id(a[i].h);
if(mi[d].w>a[i].w)
mi[d]=a[i];
}
for(int i=1;i<=tot;i++)
if(mi[i].w>mi[i-1].w)
mi[i]=mi[i-1];
for(int i=1;i<=n;i++)
if(a[i].w>mi[id(a[i].h)-1].w)
ans[a[i].id]=mi[id(a[i].h)-1].id;
else
ans[a[i].id]=-1;
}
inline void mainwork()
{
}
inline void print()
{
for(int i=1;i<=n;i++)
printf("%d%c",ans[i]," \n"[i==n]);
}
int main()
{
int t=1;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}
2227

被折叠的 条评论
为什么被折叠?



