pldzy
2022-07-16 12:10:00
AtC 传送门:F - Eating Symbols Hard
双哈希 + 差分
发现要想确定
但是上述想法暂时看起来仍有许多缺陷。注意到,我们的目的是确定
为什么哈希能实现上述的差分呢?其实,稍加思考即可发现,即
回过头来,题目要求统计的合法区间
所以,为了消除后者比前者多出的从第
知道了如何判断某一子区间是否合法之后,再考虑如何将它放进代码里实现。
看到时间限制和 map
把它们按照哈希值统计数量即可。
至此,此题被完美解决, 复杂度可过。
还要再提一个代码实现的时候需要注意的点。题目中已述,
需要双哈希。
#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(register int i = a; i <= b; ++i)
typedef long long ll;
const int maxn = 250005;
const int mod1 = 1e9 + 7, mod2 = 998244353;
int n, p[maxn], bs = 121;
char c[maxn];
map<pair<int, int>, int> mp;
pair<int, int> hsh[maxn];
ll ans;
inline int pw(int x, int p, int mod){
int res = 1;
while(p){
if(p & 1)
res = 1ll * res * x % mod;
p /= 2, x = 1ll * x * x % mod;
} return res;
}
inline pair<int, int> gh(int x, int y){
int a, b; a = b = x;
if(y < 0)
a = pw(a, mod1 - 2, mod1), b = pw(b, mod2 - 2, mod2), y *= -1;
return make_pair(pw(a, y, mod1), pw(b, y, mod2));
}
inline pair<int, int> add(pair<int, int> a, pair<int, int> b){
return make_pair((a.first + b.first) % mod1, (a.second + b.second) % mod2);
}
inline pair<int, int> mns(pair<int, int> a, pair<int, int> b){
return make_pair((a.first + mod1 - b.first) % mod1, (a.second + mod2 - b.second) % mod2);
}
inline pair<int, int> tim(pair<int, int> a, pair<int, int> b){
return make_pair((1ll * a.first * b.first) % mod1, (1ll * a.second * b.second) % mod2);
}
int main(){
scanf("%d", &n);
rep(i, 1, n){
char c; cin >> c;
p[i] = p[i - 1];
if(c == '+') hsh[i] = add(hsh[i - 1], gh(bs, p[i]));
if(c == '-') hsh[i] = mns(hsh[i - 1], gh(bs, p[i]));
if(c == '<') hsh[i] = hsh[i - 1], p[i] -= 1;
if(c == '>') hsh[i] = hsh[i - 1], p[i] += 1;
mp[hsh[i]] += 1;
}
rep(i, 1, n)
ans += mp[add(hsh[i - 1], tim(hsh[n], gh(bs, p[i - 1])))],
mp[hsh[i]] -= 1;
printf("%lld\n", ans);
return 0;
}
感谢阅读。