给定序列 c,w
对于 wi>cj,则 wi 可以匹配 cj。
在满足最大匹配的基础上,顺次输出匹配每个 cj 的 wi,要求输出的字典序最大。
题解:
考虑 Hall 定理,将 ci 和 wi 一起排序,得到序列,将 ci 视为 1,wi 视为 −1,那么答案就是 n+ 前缀和的最小值。
问题
std
#include<bits/stdc++.h>
using namespace std;
const int N=37000005,mod=1e9+7;
int turn,n,a[N],f[N],t[N];
void Sol(){
for(int i=0;i<=n;++i)
t[i]=0;
for(int i=1;i<=n;++i)
++t[a[i]];
int mex=0;
while(t[mex])++mex;
for(int i=0;i<=n;++i)
t[i]=0;
f[0]=1;
for(int i=1,j=1,k=0;i<=n;++i){
++t[a[i]];
while(t[k])++k;
if(k==mex){
while(j<i&&(a[j]>mex||t[a[j]]>1))--t[a[j++]];
f[i]=f[i-1]+f[j-1];
if(f[i]>=mod)
f[i]-=mod;
}
else
f[i]=f[i-1];
}
printf("%d\n",(f[n]-f[n-1]+mod)%mod);
}
int main(){
freopen("clods.in","r",stdin);
freopen("clods.out","w",stdout);
scanf("%d",&turn);
while(turn--){
scanf("%d",&n);
if(n<N-5){
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
}
else{
int x,y;
scanf("%d%d",&x,&y);
for(int i=2;i<=n;++i)
a[i]=(a[i-1]*x+y+i)&262143;
}
Sol();
}
return 0;
}