CF1223F题解
考场上脑残了,原思路有点小问题。
原思路:
令
对于每个 a[j]==a[i] 且 sum[i]+=1+sum[j-1]。
正解:
一个显然的结论:若区间
实际上它反过来也是成立的:若区间
(考场没想出这点
所以我们在计算
则令 a[f[i]]==a[i] 且区间
我们的问题就来到了如何求解
令 now=i-1,从 now=f[now]-1,继续查找,直至 a[now]==a[i] 为止,并 f[i]=now 。
代码如下:
for(int i = 1; i <= n; ++ i){
int now = i - 1;
while(now > 0 && a[now] != a[i]){
now = f[now] - 1;
}
if(now > 0){
//若没有满足的区间是会出现 now<=0 的情况
f[i] = now;
}
}
明显,这是会 TLE 的,那么如何简化这查找
我们定义一个 map<int,int> mp[N], a[lst]==j。我们查找时只需 f[i]=mp[i-1][a[i]] 即可。
关于 mp[i][a[i]]=i; 发现若有区间
完整代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 3e5 + 5;
int T;
int n, a[N];
map<int, int> mp[N];
int sum[N];
int ans;
signed main(){
ios::sync_with_stdio(false);
cin >> T;
while(T --){
cin >> n;
for(int i = 1; i <= n; ++ i){
cin >> a[i];
sum[i] = 0;
mp[i].clear();
} ans = 0;
for(int i = 1; i <= n; ++ i){
int j = mp[i - 1][a[i]];
swap(mp[j - 1], mp[i]);
if(j > 0){
sum[i] = sum[j - 1] + 1;
ans += sum[i];
}
mp[i][a[i]] = i;
}
cout << ans << '\n';
}
return 0;
}