Codeforces Ronda # 690 (Div. 3) E2. Cerrar tuplas (versión dura) Número de combinación de Lucas elemento inverso

outputstandard output
Esta es la versión dura de este problema. La única diferencia entre las versiones fácil y dura son las restricciones sobre k y m. En esta versión del problema, debe generar la respuesta mediante el módulo 109 + 7.

Se le da una secuencia a de longitud n que consta de números enteros de 1 a n. La secuencia puede contener duplicados (es decir, algunos elementos pueden ser iguales).

Encuentre el número de tuplas de m elementos de manera que el número máximo en la tupla difiera del mínimo en no más de k. Formalmente, necesitas encontrar el número de tuplas de m índices i1 <i2 <… <im, tal que

max (ai1, ai2,…, objetivo) −min (ai1, ai2,…, objetivo) ≤k.
Por ejemplo, si n = 4, m = 3, k = 2, a = [1,2,4,3], entonces hay dos triples de este tipo (i = 1, j = 2, z = 4 e i = 2 , j = 3, z = 4). Si n = 4, m = 2, k = 1, a = [1,1,1,1], entonces los seis pares posibles son adecuados.

Como el resultado puede ser muy grande, debe imprimir el valor módulo 109 + 7 (el resto dividido por 109 + 7).

Entrada
La primera línea contiene un solo entero t (1≤t≤2⋅105) - el número de casos de prueba. Luego siguen t casos de prueba.

La primera línea de cada caso de prueba contiene tres números enteros n, m, k (1≤n≤2⋅105, 1≤m≤100, 1≤k≤n) - la longitud de la secuencia a, el número de elementos en las tuplas y la diferencia máxima de elementos en la tupla.

La siguiente línea contiene n números enteros a1, a2,…, an (1≤ai≤n) - la secuencia a.

Se garantiza que la suma de n para todos los casos de prueba no exceda 2⋅105.

Salida La
salida t responde a los casos de prueba dados. Cada respuesta es el número requerido de tuplas de m elementos módulo 109 + 7, de modo que el valor máximo en la tupla difiera del mínimo en no más de k.

Ejemplo de entrada
Copiar
4
4 3 2
1 2 4 3
4 2 1
1 1 1 1
1 1
1
10 4 3
5 6 1 3 2 9 8 1 2 4
salida Copiar
2
6
1
20i ¡
Wuhu, cambio! !
Ordene la matriz primero como fácil, y luego recorra de m an cada vez para encontrar la posición mayor que el valor mínimo de a [i] -k, de modo que sepa la posición de los dos números cuya diferencia es menor que k. Primero tome una [i] y luego tome dos de una [i] desde la posición de a [i] -k a una [i], que se convierte en un problema de módulo un número de combinación.
Luego pegue un tablero para encontrar el elemento inverso del número de combinación basado en el teorema de Lucas, y despegue directamente. = V =.

#include<iostream>
#include<string>
#include<map>
#include<algorithm>
#include<memory.h>
#include<cmath>
#include<assert.h>
using namespace std;
typedef long long ll;
const int maxn=3e5+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
ll a[maxn];
int maxx(int a,int b,int c){
    
    
	return max(a,max(b,c));
}
int minn(int a,int b,int c){
    
    
	return min(a,min(b,c));
}
ll f[maxn]; 
ll qpow(ll a,ll b){
    
    
	ll ans = 1,base = a;
	while(b){
    
    
		if(b&1) ans = ans * base % mod;
		base = base * base % mod;
		b>>=1; 
	}
	return ans;
}
void init(){
    
    
	f[0]=1;
	for(int i=1;i<=2e5;i++){
    
    
		f[i]=f[i-1]*i%mod;
	} 
}
ll cal(ll n,ll m){
    
    
	if(n<m) return 0; 
 	return 1ll*f[n]*qpow(f[m],mod-2)%mod*qpow(f[n-m],mod-2)%mod;
}
void solve(){
    
    
	ll t;
    cin>>t;
	init();
    while(t--)
    {
    
    
		ll n,m,k;
		cin>>n>>m>>k;
		for(ll i=1;i<=n;i++){
    
    
			cin>>a[i];
		}
		sort(a+1,a+1+n);
		int cnt=0;
		ll sum=0;
		for(ll i=m;i<=n;i++){
    
    
			int x=lower_bound(a+1,a+1+n,a[i]-k)-a;
			sum+=cal(i-x,m-1);
			sum=sum%mod;
		}
		cout<<sum%mod<<endl;
    }
}
int main()
{
    
    
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	solve();
	return 0;
}
 

Supongo que te gusta

Origin blog.csdn.net/qq_45891413/article/details/111278823
Recomendado
Clasificación