题解 | Big Integer-2019牛客暑期多校训练营第三场D题

该博客主要介绍了牛客竞赛中的一道题目,涉及大整数类,即仅由1组成的整数。给定一个质数p和两个正整数n、m,求满足A(ij)(i从1到n,j从1到m)模p等于0的(i, j)对的数量。输入包含多个测试用例,每个用例包含p、n和m的值。博主提供了输出示例和问题解析。" 84136106,7829243,使用Java与Selenium自动化测试下拉框选项,"['selenium', 'java', '自动化', '下拉框']
摘要由CSDN通过智能技术生成

题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss
题目描述:
For little pupils, a very large number usually means an integer with many many digits. Let’s define a class of big integers which consists only of the digit one(11⋯1). The first few integers in this class are 1,11,111,1111⋯. Denote A(n) as the n-th smallest integer in this class. To make it even larger, we consider integers in the form of A(ab) . Now, given a prime number p, how many pairs (i,j) are there such that 1≤i≤n, 1≤j≤m, A(ij)≡0(mod p).

输入描述:
The input contains multiple cases. The first line of the input contains a single integer T (1≤T≤100), the number of cases. For each case, the input consists of a single line, which contains 3 positive integers p,n,m (p,n,m≤109).

输出描述:
Print the answer, a single integer, in one separate line for each case.

示例1:
输入
2
11 8 1
7 6 2

输出
4
2

题解:
在这里插入图片描述
在这里插入图片描述
代码:

#include <bits/stdc++.h>
using namespace std;


typedef long long LL;

vector<pair<int, int> > plist;

int pow_mod(int x, int k, int p)
{
	int ret = 1;
	for (; k; k>>=1)
	{
		if (k&1) ret = 1LL*ret*x%p;
		x = 1LL*x*x%p;
	}
	return ret;
}

int f(int n, int k)
{
	int d = 1;
	for (auto pv: plist)
	{
	 	int t = (pv.second+k-1) / k;
	 	while (t--) d *= pv.first;
    }
	return n/d;
}

int main()
{
    int T, n, m, p, d, D;
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d %d %d", &p, &n, &m);
		if (p == 2 || p == 5) {puts("0"); continue;}
		if (p == 3) // 10^d = 1 mod 27
		{
			//phi(27) = 18
			D = 18;
			p = 27;
		}
		else D = p-1;
		assert(pow_mod(10, D, p) == 1);
	  
		d = 1e9;
		for (int i = 1; i*i <= D; ++i)
		{
			if (D % i) continue;
			if (pow_mod(10, i, p) == 1)
			   d = min(d, i);
            if (pow_mod(10, D/i, p) == 1)
               d = min(d, D/i);
		}
		for (int i = 2; i*i <= d; ++i)
		{
		 	if (d % i) continue;
			int c = 0;
			while (d % i == 0) ++c, d /= i;
			plist.push_back(make_pair(i, c));	
		}
		if (d != 1) plist.push_back(make_pair(d, 1));
		LL ans = 0;
		for (int i = 1; i <= 30 && i <= m; ++i)
			ans += f(n, i);
		if (m > 30) ans += 1LL*(m-30)*f(n, 30);
		printf("%lld\n", ans);
		plist.clear();
	}
	return 0;
}

题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值