(La 11.ª competencia provincial de la Copa Blue Bridge) Pregunta de prueba H: Suma de puntajes de subcadenas (Pensamiento) (El ejemplo es incorrecto)

Enlace del tema: Cursos de proyectos destacados_Cursos populares de TI_Curso de Blue Bridge Cloud-Curso de Blue Bridge Cloud

Análisis: Creo que esta pregunta sigue siendo una buena pregunta, así que ven y anótala:

Primero, observando el rango de datos de n, sabemos que este problema solo se puede superar con la complejidad de o(n) o o(nlogn). Por supuesto, o(n^2) también puede obtener puntos parciales. Lo haré dar la solución correcta a continuación. :

Es imposible para nosotros recorrer cada subcadena en S para encontrar su valor f, pero podemos encontrar la contribución de cada carácter en S a la respuesta final y finalmente sumar las contribuciones de cada letra.Tome ababc como ejemplo, analicemos el contribución del tercer carácter a primero Supongamos que este a contribuye 1 a cada subcadena que lo contiene, entonces su contribución es 3*3=9, porque es el tercero desde la izquierda de la secuencia S también es el tercero desde Podemos elegir un número de las tres primeras posiciones en S como l, y luego elegir un número de las últimas tres posiciones en S como r, entonces cualquier secuencia [l,r] contiene Esta a, pero rápidamente descubrimos que es incorrecto pensar el problema de esta manera, porque repetirá el cálculo Por ejemplo, aba también es una subcadena de S, pero hay dos a en esta subcadena ¿A cuál a pertenece la contribución? Entonces, obviamente, no se puede calcular como ahora, es que el intervalo l del intervalo de contribución de nuestra letra actual está incluido en el intervalo desde la primera posición a la derecha de la posición donde apareció la letra actual en último lugar hasta la posición de la letra actual, y la contribución de la letra actual es La r del intervalo contiene el intervalo desde la primera posición a la izquierda de la siguiente aparición de la letra actual hasta la posición de la letra actual. Esta regulación asegura que cada subcadena select solo puede contener cada letra una vez , pero nos perderemos algunos casos de esta manera.No es difícil encontrar que para aba, nuestra letra a todavía contribuye, pero nunca podemos atravesar la subcadena que contiene la misma letra que acabamos de definir , por lo que definir la contribución de esa manera conducirá a una fuga. , para considerar cada subcadena sin falta, podemos definir la contribución de una letra de la siguiente manera: el intervalo l de la contribución de la letra actual contiene el intervalo a la actual letra una posición a la derecha de la posición donde apareció por última vez la letra actual, y La r del intervalo de contribución de la letra actual se incluye en el intervalo desde la posición de la letra actual hasta el extremo derecho de la cadena S , lo que garantiza que la contribución de la cadena se cuenta como el primer carácter cada vez que aparece una letra repetida en la subcadena seleccionada., para que la contribución de cada letra se pueda calcular sin repetición. El caso especial es que no hay la misma letra a la izquierda de una letra, entonces podemos tratarla de acuerdo con el límite izquierdo.

Aquí está el código:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
const int N=30;
vector<int>p[N];
int main()
{
	string s;
	cin>>s;
	long long len=s.size();
	s=" "+s;//让下标从1开始 
	for(int i=1;i<=len;i++)
		p[s[i]-'a'+1].push_back(i);
	long long ans=0;
	for(int i=1;i<=len;i++)
	{
		int t=s[i]-'a'+1;
		int last;
		int id=lower_bound(p[t].begin(),p[t].end(),i)-p[t].begin();//求出第i个字母是第几次出现 
		if(id) last=p[t][id-1]+1;
		else last=1;
		ans+=(i-last+1)*(len-last+1);
	}
	cout<<ans;
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/AC__dream/article/details/123972726
Recomendado
Clasificación