[Aizu1310] Find the Multiples

从后往前 把模后的值存在一个map里 每次有相同的值的时候就加入答案中

注意2 和 5是10的因数 要特殊处理

#include<cstdio>      
#include<algorithm>      
#include<cstring>      
#include<vector>      
#include<queue>    
#include<deque>    
#include<iostream>
#include<map>
#define SF scanf      
#define PF printf      
using namespace std;  
typedef long long LL;
const int MAXN = 100000;
int a[MAXN+10];
int n, S, W, p;
map <LL, LL> M;
void getA()
{
	int g = S;
    for(int i=0; i<n; i++) {
        a[i] = (g/7) % 10;
        if( g%2 == 0 ) { g = (g/2); }
        else           { g = (g/2) ^ W; }
    }
}
int main()
{
	while(SF("%d%d%d%d", &n, &S, &W, &p) && n+S+W+p)
	{
		getA();
		LL ans = 0;
		if(p == 2 || p == 5) {           // 10的因数
			int cnt = 0;
			for(int i = 0; i < n; i++)
			{
				if(a[i]) cnt++;
				if(a[i] % p == 0) ans += cnt;
			}
			cout << ans << '\n'; continue;
		}
		LL k = 1, sum = 0;
		M.clear();
		for(int i = n-1; i >= 0; i--)
		{
			sum = (k * a[i] + sum) % p;
			int tmp = M[sum]++;
			if(a[i]) ans += tmp;
			if(a[i] && sum == 0) ans++;
			k *= 10; k %= p;
		}
		cout << ans << '\n';
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值