B.
Límite de tiempo de LCM de cadena
por prueba Límite de memoria de 2 segundos por prueba
Entrada de 256 megabytes Entrada
estándar Salida Salida estándar
Definamos una operación de multiplicación entre una cadena a y un entero positivo x: a⋅x es la cadena que es el resultado de escribir x copias de uno. después de otro. Por ejemplo, “abc” ⋅ 2 = “abcabc”, “a” ⋅ 5 = “aaaaa”.
Una cadena a es divisible por otra cadena b si existe un número entero x tal que b⋅x = a. Por ejemplo, "abababab" es divisible por "ab", pero no es divisible por "ababab" o "aa".
El LCM de dos cadenas s y t (definido como LCM (s, t)) es la cadena no vacía más corta que es divisible por s y t.
Se le dan dos cadenas s y t. Busque LCM (s, t) o informe que no existe. Se puede demostrar que si existe LCM (s, t), es único.
Entrada
La primera línea contiene un número entero q (1≤q≤2000) - el número de casos de prueba.
Cada caso de prueba consta de dos líneas, que contienen cadenas syt (1≤ | s |, | t | ≤20). Cada carácter de cada una de estas cadenas es 'a' o 'b'.
Salida
Para cada caso de prueba, imprima LCM (s, t) si existe; de lo contrario, imprima -1. Se puede demostrar que si existe LCM (s, t), es único.
Ejemplo
inputCopy
3
no
en
esta dos
AAA
tamaño outputCopy no aaaaaa -1 Nota En el primer caso de prueba, "no" = "no" ⋅ 1 = "en" ⋅ 2.
En el segundo caso de prueba, “aaaaaa” = “aa” ⋅ 3 = “aaa” ⋅ 2.
Encuentre su mínimo común múltiplo y vea si las cadenas que constituyen son iguales
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
#define gt(x) x = read()
#define int long long
#define Ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0);
const int mod = 1e9 + 7;
inline int read(int out = 0)
{
char c;
while((c=getchar()) < 48 || c > 57);
while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
return out;
}
const int N = 11000;
const int M = 1e6 + 10;
signed main(){
// freopen("C:\\Users\\wwb0719\\Desktop\\stdin.txt", "r", stdin);
// Ios
int T;
gt(T);
while(T --){
string str1, str2;
cin >> str1 >> str2;
int mind = min(str1.size(), str2.size());
int cnt = 1;
for (int i = 1; ; i ++){
if (i * mind % str1.size() == 0 && i * mind % str2.size() == 0){
cnt = i;
break;
}
}
string str3;
for (int i = 1; i <= cnt; i ++){
if (str1.size() < str2.size()) str3 += str1;
else str3 += str2;
}
string str4, str5;
for (int i = 1; i <= (str3.size() / str1.size()); i ++){
str4 += str1;
}
for (int i = 1; i <= (str3.size() / str2.size()); i ++){
str5 += str2;
}
if (str4 != str5) cout << "-1" << endl;
else cout << str3 << endl;
}
return 0;
}
C. No más inversiones
Límite de tiempo
por prueba Límite de memoria de 2 segundos por prueba
Entrada de 256 megabytes Entrada
estándar Salida Salida estándar
Tiene una secuencia a con n elementos 1, 2, 3,…, k − 1, k, k − 1, k − 2,… , k− (n − k) (k≤n <2k).
Llamemos como inversión en un par de índices i <j tal que a [i]> a [j].
Suponga que tiene alguna permutación p de tamaño k y construye una secuencia b de tamaño n de la siguiente manera: b [i] = p [a [i]].
Su objetivo es encontrar tal permutación p que el número total de inversiones en b no exceda el número total de inversiones en a, y b sea lexicográficamente máximo.
Pequeño recordatorio: la secuencia de k números enteros se llama permutación si contiene todos los números enteros del 1 al k exactamente una vez.
Otro pequeño recordatorio: una secuencia s es lexicográficamente más pequeña que otra secuencia t, si s es un prefijo de t, o para la primera i tal que si ≠ ti, si <ti se cumple (en la primera posición que estas secuencias son diferentes, s tiene un número menor que t).
Entrada
La primera línea contiene un solo entero t (1≤t≤1000) - el número de casos de prueba.
La primera y única línea de cada caso de prueba contiene dos números enteros n y k (k≤n <2k; 1≤k≤105) - la longitud de la secuencia ay su máximo.
Se garantiza que la suma total de k en casos de prueba no exceda 105.
Salida
Para cada caso de prueba, imprima k enteros: la permutación p que maximiza b lexicográficamente sin aumentar el número total de inversiones.
Se puede probar que p existe y es único.
Ejemplo
inputCopy
4
1 1
2 2
3 2
4 3
outputCopy
1
1 2
2 1
1 3 2
Nota
En el primer caso de prueba, la secuencia a = [1], solo hay una permutación p = [1].
En el segundo caso de prueba, la secuencia a = [1,2]. No hay inversión en a, por lo que solo hay una permutación p = [1,2] que no aumenta el número de inversiones.
En el tercer caso de prueba, a = [1,2,1] y tiene 1 inversión. Si usamos p = [2,1], entonces b = [p [a [1]], p [a [2]], p [a [3]]] = [2,1,2] y también tiene 1 inversión.
En el cuarto caso de prueba, a = [1,2,3,2], y como p = [1,3,2] entonces b = [1,3,2,3]. Tanto a como b tienen 1 inversión y b es el máximo lexicográfico.
El par de orden inverso en la matriz a es k, y el siguiente número. Por ejemplo, [1,2,3,4,3,2] es [4,3,2], esta parte. La segunda mitad de la matriz b generada (la parte simétrica) es [p [2], p [3], p [4], p [3], p [2]]. Se puede encontrar que si la matriz p tiene En orden, entonces el número generado es 23432, y el número de pares en orden inverso debe ser igual a la matriz a, porque de hecho, la matriz b es igual a la matriz a, exactamente lo mismo, pero si esta parte del valor en p está en orden inverso, entonces el valor generado es 43234, orden inverso ¡El número de pares también es igual a una matriz! ! . Entonces, obviamente, el orden inverso es el orden lexicográfico más grande. ¡Entonces la respuesta es esta cosa! La parte asimétrica en el frente no se puede cambiar, y el par de orden inverso se cambia más que la matriz a.
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
const int mod = 1e9 + 7;
inline int read(int out = 0)
{
char c;
while((c=getchar()) < 48 || c > 57);
while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
return out;
}
const int N = 11000;
const int M = 1e6 + 10;
signed main(){
// freopen("C:\\Users\\wwb0719\\Desktop\\stdin.txt", "r", stdin);
ios;
int T;
gt(T);
while(T --){
int n, k;
gt(n), gt(k);
int res = (n - k);
int temp = (k - res - 1);
for (int i = 1; i <= temp; i ++) cout << i << " ";
for (int i = k; i > temp; i --) cout << i << " ";
cout << endl;
}
return 0;
}
D.
Límite de tiempo del programa
por prueba Límite de memoria de 2 segundos por prueba 256 megabytes de
entrada Entrada
estándar Salida Salida estándar
Se le proporciona un programa que consta de n instrucciones. Inicialmente, una sola variable x se asigna a 0. Después, las instrucciones son de dos tipos:
aumentar x en 1;
disminuir x en 1.
Se le dan m consultas con el siguiente formato:
consulta lr - ¿a cuántos valores distintos se asigna x si se ignoran todas las instrucciones entre la l-ésima y la r-ésima inclusive y el resto se ejecuta sin cambiar el orden?
Entrada
La primera línea contiene un solo entero t (1≤t≤1000) - el número de casos de prueba.
Luego sigue la descripción de los casos de prueba t.
La primera línea de cada caso de prueba contiene dos números enteros nym (1≤n, m≤2⋅105): el número de instrucciones en el programa y el número de consultas.
La segunda línea de cada caso de prueba contiene un programa - una cadena de n caracteres: cada carácter es '+' o '-' - instrucción de incremento y decremento, respectivamente.
Cada una de las siguientes m líneas contiene dos números enteros lyr (1≤l≤r≤n): la descripción de la consulta.
La suma de n sobre todos los casos de prueba no excede 2⋅105. La suma de m en todos los casos de prueba no excede 2⋅105.
Salida
Para cada caso de prueba imprime m enteros - para cada consulta l, r imprime el número de valores distintos a los que se asigna la variable x si se ignoran todas las instrucciones entre la l-ésima y la r-ésima inclusive y el resto se ejecuta sin cambiando el orden.
Ejemplo de entrada
Copia
2
8 4
- ± - ± - +
1 8
2 8
2 5
1 1
4 10
± ++
1 1
1 2
2 2
1 3
2 3
3 3
1 4
2 4
3 4
4 4
salida Copia
1
2
4
4
3
3
4
2
3
2
1
2
2
2
Nota
Las instrucciones que quedan para cada consulta del primer caso de prueba son:
programa vacío - x solo era igual a 0;
“-” - x tenía valores 0 y −1;
“- +” - x tenía valores 0, −1, −2, −3, −2 - hay 4 valores distintos entre ellos;
“± - ± - +”: los valores distintos son 1, 0, −1, −2.
¿Cuál es el número más grande y el número más pequeño que se puede obtener después de procesar un símbolo anterior, y cuál es el número cuando se procesa cada número y luego se procesa al revés para calcular cuánto se puede agregar a cada posición y cuánto se puede agregar a cada posición? Cuánto agregar, al consultar, puedes saber cuál es el número máximo y el número mínimo de este segmento en proceso de suma y resta.
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
const int mod = 1e9 + 7;
inline int read(int out = 0)
{
char c;
while((c=getchar()) < 48 || c > 57);
while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
return out;
}
const int N = 2e5 + 10;
const int M = 1e6 + 10;
int h[N], a[N], b[N], c[N], d[N];
//倒序循环,倒序后缀和
//对字符串有处理下标从1开始,读入char
signed main(){
// freopen("C:\\Users\\wwb0719\\Desktop\\stdin.txt", "r", stdin);
ios;
int T;
scanf("%lld",&T);
while(T--){
int n, m;
char s[N];
scanf("%lld%lld",&n,&m);
scanf("%s",s+1);
for(int i=1; i<=n; i++){
if(s[i]=='+')
h[i]=h[i-1]+1;
else
h[i]=h[i-1]-1;
a[i]=max(a[i-1],h[i]);
b[i]=min(b[i-1],h[i]);
}
c[n+1]=0,d[n+1]=0;
for(int i=n; i>=1; i--){
int v=s[i]=='+'?1:-1;
c[i]=max(0ll,c[i+1]+v);
d[i]=min(0ll,d[i+1]+v);
}
for(int i=1; i<=m; i++){
int l,r,A,B;
scanf("%d%d",&l,&r);
A=max(a[l-1],h[l-1]+c[r+1]);
B=min(b[l-1],h[l-1]+d[r+1]);
printf("%lld\n",A-B+1);
}
}
return 0;
}