//n个人接受邀请的条件是已经接受邀请的人数区间在l[i] , r[i]
//问怎样设置邀请顺序能使得接受邀请的人数最多
//先对其对从小到大排序
//然后维护一个set,set中存入左边满足条件的所有人,
//然后贪心策略是每次取左边满足条件的右边最小的人
//每次多邀请一个人后删除右边不满足条件的人
#include<cstdio>
#include<cstring>
#include<iostream>
#include<set>
#include<algorithm>
using namespace std ;
const int maxn = 100010 ;
int a[maxn] ; int t ;int n ;
int vis[maxn] ;
struct node
{
int l ,r ,id ;
bool operator < (const struct node tmp) const
{
if(l == tmp.l)
return r < tmp.r ;
return l<tmp.l ;
}
} p[maxn];
multiset<pair<int, int> > s ;
multiset<pair<int , int> >::iterator it ;
int main()
{
// freopen("in.txt" ,"r" , stdin) ;
scanf("%d" , &t) ;
memset(vis , 0 , sizeof(vis)) ;
while(t--)
{
scanf("%d" , &n) ;
for(int i = 1;i <= n;i++)
scanf("%d" ,&p[i].l) ,p[i].id = i ;
for(int i = 1;i <= n;i++)
scanf("%d" , &p[i].r) ;
sort(p + 1 , p + 1 + n) ;
int ans = 0 ;
int i = 1;
s.clear() ;
while(1)
{
while(ans >= p[i].l && i <= n)
{
s.insert(make_pair(p[i].r , p[i].id)) ;
i++;
}
if(!s.size())break;
while(s.size())
{
it = s.begin() ;
if(it->first >= ans)
break;
s.erase(s.begin()) ;
}
if(s.size())
{
it = s.begin();
a[++ans] = it->second ;
vis[it->second] = 1;
s.erase(s.begin()) ;
}
}
printf("%d\n" ,ans) ;
for(int i = 1;i <= n;i++)
if(!vis[i])
a[++ans] = i ;
else vis[i] = 0 ;
for(int i = 1;i <= ans ;i++)
printf("%d%c" , a[i] , i == ans ? ‘\n‘:‘ ‘) ;
}
return 0 ;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-12 20:27:03