求前缀和:
for(int i=1;i<=n;i++){
sumx[i]+=sumx[i-1];
sumy[i]+=sumy[i-1];
}
从后往前跑,每次更新前缀和坐标最前面的下标,如果前一个前缀和的坐标+x,+y在map出现过
那么就有n-map[{x+sumx[i-1],y+sumy[i-1]}]+1种可能:
for(int i=n;i>=1;i--){
mp[{sumx[i],sumy[i]}]=i;
if(mp[{x+sumx[i-1],y+sumy[i-1]}]){
ans+=n-mp[{x+sumx[i-1],y+sumy[i-1]}]+1;
//cout<<i<<endl;
}
}
最终代码:
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
#define pii pair<int,int>
using namespace std;
const int N=1e6+5,mod=1e9+7;
int n,m,k,t;
int vis[N];
int a[N];
int sumx[N],sumy[N];
map<pii,int>mp;
signed main() {
int x,y;
cin>>n>>x>>y;
sumx[0]=0;
sumy[0]=0;
string s;
cin>>s;
if(x==0&&y==0){
cout<<(n+1)*n/2;
return 0;
}
for(int i=1;i<=n;i++){
if(s[i-1]=='A'){
sumx[i]=-1;
}
else if(s[i-1]=='S'){
sumy[i]=-1;
}
else if(s[i-1]=='D'){
sumx[i]=1;
}
else {
sumy[i]=1;
}
}
for(int i=1;i<=n;i++){
sumx[i]+=sumx[i-1];
sumy[i]+=sumy[i-1];
}
int ans=0;
for(int i=n;i>=1;i--){
mp[{sumx[i],sumy[i]}]=i;
if(mp[{x+sumx[i-1],y+sumy[i-1]}]){
ans+=n-mp[{x+sumx[i-1],y+sumy[i-1]}]+1;
//cout<<i<<endl;
}
}
cout<<ans<<endl;
return 0;
}