Link: https://codeforces.com/contest/1625/problem/B
Ideia: O que pensei originalmente era encontrar o mesmo número com dois ponteiros e, em seguida, obter o comprimento máximo da substring com base no subscrito. Mais tarde, descobri que o tempo expiraria, então pensei em usar vetor + par para armazenar os números e os subscritos correspondentes e, em seguida, classificar os números para que números iguais fossem adjacentes. Em seguida, encontre o comprimento da substring com base nos subscritos e, em seguida, mantenha um valor máximo. É isso.
O comprimento da maior substring é a posição do número anterior + n - a posição do número seguinte.
Meu código:
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,a;
cin>>n;
int num[n];
vector<PII> q;
q.clear();
for(int i=0;i<n;i++)
cin>>num[i],q.push_back({
num[i],i+1});
sort(q.begin(),q.end());
int ans=0;
for(int i=0;i<n-1;i++)
if(q[i].first==q[i+1].first)
ans=max(ans,n-q[i+1].second+q[i].second);
if(ans==0) ans=-1;
cout<<ans<<"\n";
}
}
Código de outra pessoa:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
int num[N],re[N],la[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,a;
cin>>n;
memset(num, 0, sizeof num);
memset(re, -1, sizeof re);
memset(la, 0, sizeof la);
for(int i=0;i<n;i++)
cin>>num[i];
int ans=0;
for(int i=0;i<n;i++)
{
if(re[num[i]]!=-1)
{
ans=max(ans,la[num[i]]+n-i);
la[num[i]]=i;
}
else
{
re[num[i]]++;
la[num[i]]=i;
}
}
if(ans==0) ans=-1;
cout<<ans<<endl;
}
}
Desta forma, o array re armazena o número de vezes que o número correspondente aparece, e o array la armazena a posição onde o número correspondente apareceu pela última vez. Então, quando o valor correspondente de re for maior que -1, significa que há números duplicados, atualize o máximo e atualize a matriz la.
Quando o número fornecido por este método é muito grande, o array não pode ser aberto tão grande, portanto ainda tem limitações. Eu ainda recomendo minha abordagem.