Codeforces Global Round 12 D. Compresión de calificación (思维)

Descripción del Título

En la plataforma de programación competitiva CodeCook, cada persona tiene un gráfico de calificación descrito por una matriz de números enteros a de longitud n. Ahora está actualizando la infraestructura, por lo que ha creado un programa para comprimir estos gráficos.
El programa funciona de la siguiente manera. Dado un parámetro entero k, el programa toma el mínimo de cada subconjunto contiguo de longitud k en a.
Más formalmente, para una matriz a de longitud n y un número entero k, defina la matriz de compresión k de a como una matriz b de longitud n − k + 1, tal que
bj = minj≤i≤j + k − 1ai
Por ejemplo , la matriz de 3 compresiones de [1,3,4,5,2] es [min {1,3,4}, min {3,4,5}, min {4,5,2}] = [1 , 3,2].
Una permutación de longitud m es una matriz que consta de m enteros distintos de 1 am en orden arbitrario. Por ejemplo, [2,3,1,5,4] es una permutación, pero [1,2,2] no es una permutación (2 aparece dos veces en la matriz) y [1,3,4] tampoco es una permutación. permutación (m = 3 pero hay 4 en la matriz).
Una matriz de compresión k hará felices a los usuarios de CodeCook si se trata de una permutación. Dada una matriz a, determine para todo 1≤k≤n si los usuarios de CodeCook estarán contentos después de una k-compresión de esta matriz o no.

Aporte

La primera línea contiene un solo entero t (1≤t≤104) - el número de casos de prueba.
La primera línea de la descripción de cada caso de prueba contiene un único entero n (1≤n≤3⋅105): la longitud de la matriz.
La segunda línea de la descripción de cada caso de prueba contiene n números enteros a1,…, an (1≤ai≤n) - los elementos de la matriz.
Se garantiza que la suma de n para todos los casos de prueba no exceda 3⋅105.

Producción

Para cada caso de prueba, imprima una cadena binaria de longitud n.
El k-ésimo carácter de la cadena debe ser 1 si los usuarios de CodeCook estarán contentos después de una k-compresión de la matriz a, y 0 en caso contrario.

Ejemplo

entrada
5
5
1 5 3 4 2
4
1 3 2 1
5
1 3 3 3 2
10
1 2 3 4 5 6 7 8 9 10
3
3 3 2
salida
10111
0001
00111
1111111111
000

Nota

En el primer caso de prueba, a = [1,5,3,4,2].
La 1-compresión de a es [1,5,3,4,2] y es una permutación.
La compresión 2 de a es [1,3,3,2] y no es una permutación, ya que 3 aparece dos veces.
La compresión 3 de a es [1,3,2] y es una permutación.
La compresión 4 de a es [1,2] y es una permutación.
La compresión 5 de a es [1] y es una permutación.

Idea general

Dada una matriz a [] de longitud n, encuentre todas las subsecuencias de longitud k en a [] y tome el valor mínimo de cada subsecuencia para obtener una nueva secuencia. Y juzgue si esta nueva secuencia es una permutación (una permutación que contiene n números satisface dos condiciones: 1.n números no tienen repetición. 2. El rango de valores de n números es [1, n]), si es una permutación, es 1., de lo contrario es 0.
k toma [1, n] para obtener la secuencia 01.

Análisis de temas

Primero, un [] para el tipo de cubo 用cnt[i]记录a[]在等于i的数有几个.
Para k = 1 y n, se requiere un juicio especial. Para k = 1, solo es necesario juzgar si la secuencia completa es una permutación. Cuando k = n, solo es necesario juzgar si hay 1 en la secuencia ( porque solo hay una subsecuencia de longitud n).

Podemos enumerar todos los k de mayor a menor (porque cuanto mayor es la k, menor es el número de subsecuencias, mejor es el cálculo), y cada vez que verificamos si el valor máximo de la disposición actual es legal (consulte el código para método de juicio). Debido a que se reduce la longitud de la subsecuencia, solo se aumentará el valor máximo y no se verán afectados otros valores de la secuencia .

Además, se puede deducir que si la secuencia obtenida por un cierto valor de k no es una permutación, entonces los valores subsiguientes (2 a k-1) tampoco serán permutaciones.

el código se muestra a continuación
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#include <unordered_map>
#include <queue>
#include <vector>
#include <set>
#include <bitset>
#include <algorithm>
#define LL long long
#define PII pair<int,int>
#define x first
#define y second
using namespace std;
const int N=3e5+5,mod=1e9+7;
int a[N],cnt[N],ans[N];
bool check(int n)			//判断a[]序列是否为排列
{
    
    
	for(int i=1;i<=n;i++)
		if(cnt[i]!=1) return false;
	return true;
}
int main()
{
    
    
	int t;
	scanf("%d",&t);
	while(t--)
	{
    
    
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%d",&a[i]),cnt[a[i]]++;
		if(cnt[1]) ans[n]=1;			//如果序列中存在1,那么k=n合法
		if(check(n)) ans[1]=1;			//判断k=1时是否合法
		
		int l=1,r=n;
		for(int i=n;i;i--)				//从大到小枚举k(i)
		{
    
    
			if(ans[n]==0) break;
			ans[i]=1;					//当循环到i时,说明k=i合法
			int m=n-i+1;				//当前k值下排列序列中的最大值m
			//判断k=i+1时是否能构成一个排列
			if(--cnt[m]==0&&(a[l]==m||a[r]==m)&&cnt[m+1])		//如果a[]中存在两个m或者不存在m+1,就无法构成一个排列
			{
    
    	//如果m的两边都是比它大的数,那么k=i+1也无法构成一个排列。
				if(a[l]==m) l++;		//只有当每次的最大值都在l或r上时,才能保证[l,r]区间内的数要大于区间外的数
				if(a[r]==m) r--;		//收缩区间
			}
			else break;					//如果前面的判断不合法,可直接中断循环
		}
		
		for(int i=1;i<=n;i++) printf("%d",ans[i]),cnt[i]=ans[i]=0;
		puts(""); 
	}
	return 0; 
}

Supongo que te gusta

Origin blog.csdn.net/li_wen_zhuo/article/details/114268205
Recomendado
Clasificación