1. 程式人生 > 其它 >CodeForces Round 693 E

CodeForces Round 693 E

技術標籤:Acm 貪心

連結:
https://codeforces.ml/contest/1472/problem/E
題目大意:
有T(1 ≤ \leq T T T ≤ \leq 1 0 4 10^4 104)組資料,你有N(1 ≤ \leq N N N ≤ \leq 2 ∗ 1 0 5 2*10^5 2105)張照片.每張照片給定 w i , h i w_i,h_i wi,hi(1 ≤ \leq w i , h i w_i,h_i wi,hi ≤ \leq 1 0 9 10^9 109)表示寬度和高度.定義兩張照片 i , j i,j i,j,j包含i的含義是: w i < w j , h i < h j w_i<w_j,h_i<h_j

wi<wj,hi<hj或者 h i < w j , w i < h j h_i<w_j,w_i<h_j hi<wj,wi<hj.求 i ϵ [ 1 , n ] i\epsilon[1,n] iϵ[1,n] i i i照片所包含的 j j j照片,如果沒有就輸出-1.(注:1 ≤ \leq ∑ i = 1 T N i \displaystyle\sum_{i=1}^T N_i i=1TNi ≤ \leq 2 ∗ 1 0 5 2*10^5 2105)
分析:
每張照片 i i i我們可以根據大小把令 w i = m i n ( w i , h i ) , h i = m a x ( w i , h i ) w_i=min(w_i,h_i),h_i=max(w_i,h_i)
wi=min(wi,hi),hi=max(wi,hi)
.這樣就解決了分類討論的問題.然後根據先 h i h_i hi,後 w i w_i wi的順序從小到大,進行雙關鍵字排序. 定義一個數 l a s t last last,表示 h l a s t < h c u r r e n t , h l a s t + 1 = h c u r r e n t h_{last}<h_{current},h_{last+1}=h_{current} hlast<hcurrent,hlast+1=hcurrent,那麼 a n s c u r r e n t = f i n d i n d e x ( m i n w i d e 1.. l a s t ) ans_{current}=find index(minwide_{1..last})
anscurrent=findindex(minwide1..last)
,此時計算 f i n d i n d e x findindex findindex我們只需要一邊更新最小值,一邊求解就可以了.

#include<bits/stdc++.h>
#define MAXN 200005
using namespace std;

int n,Min[MAXN],Minval[MAXN];
struct Data{
	int x,y,id,ans;
}a[MAXN];

bool Cmp_(Data Cmp1,Data Cmp2){
	return(Cmp1.y<Cmp2.y)||(Cmp1.y==Cmp2.y&&Cmp1.x<Cmp2.x);
}

bool Cmp(Data Cmp1,Data Cmp2){
	return(Cmp1.id<Cmp2.id);
}

int main(){
	int Tmp;
	cin>>Tmp;
	while(Tmp--){
		cin>>n;
		for(int i=1;i<=n;++i){
			int xx,yy;
			cin>>xx>>yy; 
			a[i].x=min(xx,yy);
			a[i].y=max(xx,yy);
			a[i].id=i;
			a[i].ans=-1;
		}
		sort(a+1,a+n+1,Cmp_);
		Min[1]=a[1].x;
		Minval[1]=a[1].id;
		for(int i=2;i<=n;++i){
			if(Min[i-1]<a[i].x){
				Minval[i]=Minval[i-1];
				Min[i]=Min[i-1];
			}
			else{
				Minval[i]=a[i].id;
				Min[i]=a[i].x;
			}
		}
		int l=0;
		Min[0]=INT_MAX; 
		for(int i=2;i<=n;++i){
			if(a[i].y>a[i-1].y)l=i-1;
			if(Min[l]<a[i].x)a[i].ans=Minval[l];
		}
		sort(a+1,a+n+1,Cmp);
		for(int i=1;i<=n;++i)
		cout<<a[i].ans<<" ";
		puts("");
	}
	return 0;
}

時間複雜度O( ∑ i = 1 T N i l o g N i \displaystyle\sum_{i=1}^T N_ilogN_i i=1TNilogNi)