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 ...
随机推荐
- 关于es6 let var const 以及Symbol的总结
```javascript //es6新增块级作用域.声明变量用关键字let const , // es5中只有函数作用域和全局作用域,声明变量用关键字var // let 和const 声明的变量 ...
- Java入门-jdk安装与环境搭建
计算机 计算机的组成:硬件+软件 1.硬件 1.1CPU 好比人的大脑 主要负责数据的运算以及控制 1.2内存 存储数据(临时存储) 缺点: 如果断电,数据丢失 如果程序关闭或退出,数据丢失 1.3硬 ...
- DTCC 2020 | 阿里云李飞飞:云原生分布式数据库与数据仓库系统点亮数据上云之路
简介: 数据库将面临怎样的变革?云原生数据库与数据仓库有哪些独特优势?在日前的 DTCC 2020大会上,阿里巴巴集团副总裁.阿里云数据库产品事业部总裁.ACM杰出科学家李飞飞就<云原生分布式数 ...
- 剑指offer-56数组中数字出现的次数
题目 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 输入:nums = [4,1,4,6] 输出 ...
- 关联实现下-jsonpath取值(有难度!!耗时长)
re的使用参考:正则表达式基础及re模块:https://www.cnblogs.com/dream66/p/12953729.html import restr1 = '{"access_ ...
- 【Linux】snmp在message中报错: /etc/snmp/snmpd.conf: line 311: Error: ERROR: This output format has been de
Apr 17 17:36:17 localhost snmpd[2810]: /etc/snmp/snmpd.conf: line 311: Error: ERROR: This output for ...
- Poj-P3468题解【线段树】
本文为原创,转载请注明:http://www.cnblogs.com/kylewilson/ 题目出处: http://poj.org/problem?id=3468 题目描述: 给N个数A1, A2 ...
- Redis 实战 —— 04. Redis 数据结构常用命令简介
字符串 P39 Redis 的字符串是一个有字节组成的序列,可以存储以下 3 种类型的值:字节串(byte string).整数.浮点数. 在需要的时候, Redis 会将整数转换成浮点数.整数的取值 ...
- file转化为binary对象发送给后台
具体代码如下: function filechange(e) { var file = $('#filed').get(0).files[0]; var fileSize = file.size, f ...
- Py迭代和迭代器,生成器,生产者和消费者模型
迭代器iter 1.迭代的含义: 每次生成的结果依赖于上一次.问路,先问第一个人,第一个人不知道他就说第二个人知道,然后去找第二个人.第二个人不知道就说第三个人知道,然后去找第三个人 2.递归的含义: ...