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 ...
随机推荐
- Command3
压缩和解压 gzip gunzip .gz 指定文件必须带后缀 gzip file filename.gz zip unzip .zip unzip filename.zip directory zi ...
- 查找linux系统下的端口被占用进程的两种方法 【转】
在linux下开发时,你的软件可能要使用某一个端口,或者想查找某一个端口是否被占用.需要怎么做呢??这的确是一个比较烦恼的问题,我也此为这个苦恼过.但是通过查找man手册,还是同事的交流.总结出来两种 ...
- python模块详解 | progressbar
参考官方文档:https://pypi.org/project/progressbar/#description progressbar 安装: pip install progressbar pro ...
- 开发中经常使用到的Xcode快捷键
工欲善其事必先利其器. 有了这些快捷键加持,你写代码不仅很6而且还很好看. 这些快捷键都是平时使用频率非常高的,今天整理出来分享给大家了. 左缩进:Cmd + [ 右缩进:Cmd + ] 代码格式化/ ...
- 数据分析——Numpy/pandas
NumPy NumPy是高性能科学计算和数据分析的基础包.部分功能如下: ndarray, 具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组. 用于对整组数据进行快速运算的标准数学函数(无需编 ...
- 同步与异步 Python 有何不同?
你是否听到人们说过,异步 Python 代码比"普通(或同步)Python 代码更快?果真是那样吗? 1 "同步"和"异步"是什么意思? Web 应用 ...
- (10)-Python3之--引入
1.什么是模块 .py文件就是模块 模块名有命名要求: 1.不要以数字.下划线开头.特殊符号.也不要以中文开头. 2.通常来说,都是以字母开头. 3.不要以关键字来命名.内置函数.内置模块.不要以第三 ...
- js input相关事件(转载)
1.onfocus 当input 获取到焦点时触发. 2.onblur 当input失去焦点时触发,注意:这个事件触发的前提是已经获取了焦点再失去焦点的时候才会触发该事件,用于判断标签为空.3.o ...
- 0到1:微信后台系统的演进之路 原创 张文瑞 InfoQ 2016-01-14
0到1:微信后台系统的演进之路 原创 张文瑞 InfoQ 2016-01-14
- Model(metaclass=ModelBase)
Python装饰器.metaclass.abc模块学习笔记 - 王智愚 - 博客园 https://www.cnblogs.com/Security-Darren/p/4094959.html dja ...