https://ac.nowcoder.com/acm/problem/15809
#include<iostream>
#include<map>
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
//首先明确一个概念 d(x)=x%(k-1)。
//原因:a[l]+a[l+1]...+a[r],其中每2个数加和≥k那么会由1和余k部分表示,也就是最终结果也由 1和余k部分表示
//数位和的变化是每k转化为1,也就是丢失的是k-1的整数倍换句话说每次迭代的过程中,模k-1的余数是不会改变的
//由于正常求余为k,但为了方便,把题中求余改为k-1,所以b=0和b=k-1时特殊,单独考虑。 正面考虑b=0情况,然后做差求出b=k-1。
//b=0情况,子串均为0,即把连续子串为0的看作一个集合。例如:2051000,分别+1,+1,+2,+3。分别为0(0),(0(1),0(2)|0(1)0(2),0(3)|0(2)0(3)|0(1)0(2)0(3) )->可以看作一个3个不同0的集合
//由于nmax=1e5,n*(n+1)/2=5e9,超过int,用ll
int main(){
int a[maxn];
map<int,int> m;
int k,b,n,cnt=0,sum=0;
ll ans=0,zero=0;
cin>>k>>b>>n;
for(int i=0;i<n;i++){ //记录0的个数,不含k-1
cin>>a[i];
if(a[i]) cnt=0;
else cnt++,zero+=cnt;
}
if(b==0) {
cout<<zero;
return 0;
}
m[0] = 1;
if(b==k-1) b=0,ans=-zero;
for(int i=0;i<n;i++){ //遍历r,查找d[l,r]=b的个数,然后d[r]-d[l-1]=b,变式成d[r]-b=d[l-1],数学考试 和 珂朵莉与宇宙 的结合
sum=(sum+a[i])%(k-1); //sum代表前缀和 d[r]
ans+=m[(sum-b+k-1)%(k-1)];
m[sum]++; //完事后,d[r]变d[l],记录+1
}
cout<<ans;
}