题目大意
敌人有
n
个侏儒排成一个环,自己有
精灵依次进入和侏儒决斗,如果他配对的侏儒已经有对手,就顺势针找下一个。
找到一种安排顺序,求最多能赢多少局。
Data Constraint
n≤5×105
题解
设
Ri
表示一开始分配的编号小于等于
i
的数量。可以证明必定存在一个位置满足所有的精灵都不会跨过这个位置。即对于一个位置
然后从
m
这个位置断开环,贪心的放,用一个set维护。
时间复杂度:
SRC
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
using namespace std ;
#define N 500000 + 10
vector < int > B[N] ;
set < int > Q ;
int R[N] ;
int A[N] , P[N] , V[N] ;
int n , ans ;
int main() {
freopen( "fight.in" , "r" , stdin ) ;
freopen( "fight.out" , "w" , stdout ) ;
scanf( "%d" , &n ) ;
for (int i = 1 ; i <= n ; i ++ ) {
scanf( "%d" , &A[i] ) ;
B[A[i]].push_back(i) ;
R[A[i]] ++ ;
}
for (int i = 1 ; i <= n ; i ++ ) scanf( "%d" , &P[i] ) ;
for (int i = 1 ; i <= n ; i ++ ) scanf( "%d" , &V[i] ) ;
int wz = 0 , Minv = 0x7FFFFFFF ;
for (int i = 1 ; i <= n ; i ++ ) {
R[i] += R[i-1] ;
if ( R[i] - i < Minv ) {
Minv = R[i] - i ;
wz = i ;
} else if ( R[i] - i == Minv && B[i].size() > 0 ) wz = i ;
}
for (int i = wz % n + 1 ; ; i = (i % n) + 1 ) {
for (int j = 0 ; j < (signed)B[i].size() ; j ++ ) {
Q.insert( V[B[i][j]] ) ;
}
if ( *Q.rbegin() < P[i] ) Q.erase(Q.begin()) ;
else {
ans ++ ;
Q.erase( Q.upper_bound( P[i] ) ) ;
}
if ( i % n + 1 == wz % n + 1 ) break ;
}
printf( "%d\n" , ans ) ;
return 0 ;
}
以上.