2019牛客多校第三场D-Big Integer
题意
定义\(A(n)\) 为 n个1表示的十进制数,例如\(A(3) = 111\)
然后对于\(1 \le i \le n,1\le j \le m\) 问有多少的 \(pairs(i,j)\)满足\(A(i^j) \equiv 0 \pmod p\)
分析
$11\cdots 111 = {10^n-1 \over 9} \equiv 0\pmod p $
等价于\(10^n \equiv 1\pmod {9p}\)
当 \(p = 2,5\)时,显然答案为0(因为\(11\cdots 111\) 模2或模5肯定不是0)
当 \(p \neq 2,5\) 时,有\(gcd(10,9p) = 1\),有\(10^{\phi(9p)} \equiv 1\pmod {9p}\)
\(\phi(9p)\)是欧拉函数,这个式子由欧拉定理可知
所以只需要找\(10^i mod ~9p\) 的最小循环节d,显然 \(d|\phi(9p)\) ,所以只需要暴力找\(\phi(9p)\)的因子,找到最小的符合条件的即可
”显然成立“部分证明:
设d不是 \(n = \phi(9p)\) 的因子,那么 \(n = kd + r\) , 又\(10^{n} \equiv 1\pmod {9p}\) ,\(10^{d} \equiv 1\pmod {9p}\) ,所以有\(10^r \equiv 1\pmod {9p}\),r比d小,与d最小矛盾
接下来只需要找有多少个\(pair(i,j), d|i^j\)
把 d 质因数分解:\(d=p_1^{k_1}p_2^{k_2}\cdots p_l^{k_l}\), 要使得 \(i^j\) 是 \(d\) 的倍数,那么在 \(i^j\) 的质因数分解中 \(p_1,p_2\cdots p_l\) 的指数中都要比\(d\) 中的大,所以我们考虑 j 固定的时候,有多少个 i 可以满足条件。
很容易就可以想到
\(i\) 必须是 \(g = p_1^{\lceil {k_1\over j} \rceil} p_2^{\lceil {k_2\over j} \rceil}\cdots p_l^{\lceil {k_l\over j} \rceil}\) 的倍数(至于为什么上取整,可以想一想,因为要求最小的 \(x\), 有\(x*j >= k_1 \&\& x*(j-1) < k_1\) )。因此一共有\(n\over g\)个合法的\(i\)。
取\(mx = max(k_1,k_2,\cdots k_l)\) 那么 我们只需要依次计算\(j,(j \in [1,mx])\) 就可以了。而对于 \(j > mx\) 的部分,合法的 i 的个数都是一样的。不妨带入上式看一看。
计算原理就是这样。但是实际操作又遇到了一些坑..
计算\(\phi(9p)\) 后,枚举因数找循环节时,快速幂会爆ll,所以要用快速乘(因为p最大1e9)
另一种方法是,因为欧拉函数是积性函数,所以如果9和p互质,那么\(\phi(9p) = phi(9) *(p-1)\) ,对\(p=3\)的情况进行特判,而对于其他情况只需要枚举\(\phi(p)\)的因子即可。
因为当9和p互质时,若有 n 对 $10^n \equiv 1\pmod {9p} $成立,那么一定有\(10^n \equiv 1\pmod {p}\) 成立
代码
计算\(\phi(9p)\)快速乘方法
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
int n,m,p;
int q[N],c[N],tot;
ll mul(ll a, ll b, ll p) {
ll ret = 0;
while (b) {
if (b & 1) ret = (ret + a) % p;
b /= 2;
a = (a + a) % p;
}
return ret;
}
ll ksm(ll a,ll b,ll mod){
ll res = 1;
for(;b;b>>=1){
if(b&1)res = mul(res,a,mod);
a = mul(a,a,mod);
}
return res;
}
ll getphi(ll x){
ll res = x;
for(ll i=2;i*i <= x;i++){
if(x % i == 0){
res = res / i * (i-1);
while(x % i == 0)x /= i;
}
}
if(x > 1)res = res / x * (x - 1);
return res;
}
int main(){
int T;scanf("%d",&T);
while(T--){
scanf("%d%d%d",&p,&n,&m);
if(p == 2 || p == 5){
puts("0");
continue;
}
ll phi = getphi(9ll * p);
ll fac = 1e18;
for(ll i=2;i*i<=phi;i++){
if(phi % i == 0){
if(ksm(10,i,p * 9ll) == 1)fac = min(fac,i);
if(ksm(10,phi/i,p * 9ll) == 1)fac = min(fac,phi/i);
}
}
tot = 0;
for(int i=2;i*i<=fac;i++){
if(fac % i == 0){
q[++tot] = i;c[tot] = 0;
while(fac % i == 0)fac /= i,c[tot] ++;
}
}
if(fac > 1)q[++tot] = fac,c[tot] = 1;
ll res = 0;
int mx = 0;
for(int i=1;i<=tot;i++) mx = max(mx,c[i]);
for(int j=1;j <= mx && j <= m;j++){
int now = 1;
for(int i=1;i<=tot;i++){
int k = c[i] / j + (c[i]%j != 0);
for(int o = 1;o<=k;o++)now *= q[i];
}
res += n / now;
}
if(m > mx){
int now = 1;
for(int i=1;i<=tot;i++)now *= q[i];
res += 1ll * (m-mx) * (n / now);
}
printf("%lld\n",res);
}
return 0;
}
标程用的方法
#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 特判p = 3
{
//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;
}
2019牛客多校第三场D-Big Integer的更多相关文章
- 2019牛客多校第三场 F.Planting Trees
题目链接 题目链接 题解 题面上面很明显的提示了需要严格\(O(n^3)\)的算法. 先考虑一个过不了的做法,枚举右下角的\((x,y)\),然后二分矩形面积,枚举其中一边,则复杂度是\(O(n^3 ...
- 2019牛客多校第三场D BigInteger——基础数论
题意: 用 $A(n)$ 表示第 $n$ 个只由1组成分整数,现给定一个素数 $p$,求满足 $1 \leq i\leq n, 1 \leq j \leq m, A(i^j) \equiv 0(mo ...
- [2019牛客多校第三场][G. Removing Stones]
题目链接:https://ac.nowcoder.com/acm/contest/883/G 题目大意:有\(n\)堆石头,每堆有\(a_i\)个,每次可以选其中两堆非零的石堆,各取走一个石子,当所有 ...
- [题解]Magic Line-计算几何(2019牛客多校第三场H题)
题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意: 给你偶数个点的坐标,找出一条直线将这n个点分成数量相等的两部分 并在这条直线上取不同的两个点,表示 ...
- [题解]Crazy Binary String-前缀和(2019牛客多校第三场B题)
题目链接:https://ac.nowcoder.com/acm/contest/883/B 题意: 给你一段长度为n,且只有 ‘0’ 和 ‘1’ 组成的字符串 a[0,...,n-1].求子串中 ‘ ...
- 2019牛客多校第三场A Graph Games 分块思想
题意:给你一张无向图,设s(x)为与x直接相连的点的集合,题目中有两种操作: 1:1 l r 将读入的边的序列中第l个到第r个翻转状态(有这条边 -> 没这条边, 没这条边 -> 有这条边 ...
- 启发式分治:2019牛客多校第三场 G题 Removing Stones
问题可以转换为求有多少个区间数字的总和除2向下取整大于等于最大值.或者解释为有多少个区间数字的总和大于等于最大值的两倍(但是若区间数字总和为奇数,需要算作减1) 启发式分治: 首先按最大值位置分治,遍 ...
- 2019牛客多校第三场B-Crazy Binary String(前缀和+思维)
Crazy Binary String 题目传送门 解题思路 把1记为1,把0记为-1,然后求前缀和,前缀和相等的就说明中间的01数一样.只要记录前缀和数值出现的位置即可更新出答案. 代码如下 #in ...
- 2019牛客多校第三场H-Magic Line
Magic Line 题目传送门 解题思路 因为坐标的范围只有正负1000,且所有点坐标都是整数,所以所有点相连构成的最大斜率只有2000,而我们能够输出的的坐标范围是正负10^9.所以我们先把这n个 ...
- 2019牛客多校第三场J-LRU management(map+双向链表)
LRU management 题目传送门 解题思路 用map索引对应地址,用双向链表维护序列. 代码如下 #include <bits/stdc++.h> #define INF 0x3f ...
随机推荐
- 初识 D3.js :打造专属可视化
一.前言 随着现在自定义可视化的需求日益增长,Highcharts.echarts等高度封装的可视化框架已经无法满足用户各种强定制性的可视化需求了,这个时候D3的无限定制的能力就脱颖而出. 如果想要通 ...
- Debian安装HomeBrew
前言 HomeBrew 的用处我想使用 Mac 的开发人员都知道, 本篇讲解如何在 Debian 上安装 BrewLinux 更新: 后来发现并不是很好用, 不建议使用 官方推荐的脚本安装 注意这里只 ...
- 爬虫-urllib模块的使用
urllib是Python中请求url连接的官方标准库,在Python3中将Python2中的urllib和urllib2整合成了urllib.urllib中一共有四个模块,分别如下: request ...
- LeetCode 二分查找模板 III
模板 #3: int binarySearch(vector<int>& nums, int target){ if (nums.size() == 0) return -1; i ...
- 魔法方法推开Python进阶学习大门
热爱Python Python是Guido van Rossum设计出来的让使用者觉得如沐春风的一门编程语言.2020年11月12日,64岁的Python之父宣布由于退休生活太无聊,自己决定加入Mic ...
- 【Spring】Spring的数据库开发 - 1、Spring JDBC的配置和Spring JdbcTemplate的解析
Spring JDBC 文章目录 Spring JDBC Spring JdbcTemplate的解析 Spring JDBC的配置 简单记录-Java EE企业级应用开发教程(Spring+Spri ...
- WIN7系统没有USB驱动和以太网驱动如何操作
| 欢迎关注个人公众号 zclinux_note 第一时间获取关于linux使用的技巧.探索Linux的奥秘 | 今天在单位安装了一台win7纯净版,但是安装完成后发现usb没有反应,插上网 ...
- 1.5V转3.3V升压电路图和1.5V转3.3V的电源芯片
1.5V转3.3V的电路图需要材料:PW5100芯片,2个贴片电容,1个贴片电感.即可组成一个DC-DC同步升压高效率电路图,可提供稳定的3.3V输出电压. 1.5V转3.3V的电源芯片 1.5V转3 ...
- 夯实基础系列一:Java 基础总结
前言 大学期间接触 Java 的时间也不短了,不论学习还是实习,都让我发觉基础的重要性.互联网发展太快了,各种框架各种技术更新迭代的速度非常快,可能你刚好掌握了一门技术的应用,它却已经走在淘汰的边缘了 ...
- VMware虚拟机提示“以独占方式锁定此配置文件失败”!!!
VMware异常关闭后再次启动提示"以独占方式锁定此配置文件失败"!!! 前几日在使用VMware虚拟机的时候,虚拟机突然出现了卡顿,然后就把电脑关机了重启,结果再次打开虚拟机的时 ...