牛客-k进制数(前缀和)

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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值