目录
质数
质数的判定
试除法
MillerRobbin(米勒罗宾素数测试)
素数筛法
埃氏筛
线性筛
区间筛
Prime Distance
HDU6069 Counting Divisors(区间分解质因数)
阶乘分解
ural1055 Combinations
约数
算术基本定理的扩展
数值分块
BZOJ1257 余数之和
BZOJ2956 模积和
最大公约数
欧几里得算法
区间GCD
HDU 5726 GCD
HDU 5869 Different GCD Subarray Query
欧拉函数
POJ2478 Farey Sequence
POJ3090 Visible Lattice Points
POJ2480 Longge's problem
BZOJ 4804 欧拉心算 心酸
HDU5780 gcd
HDU4676 Sum Of Gcd
同余
同余类
剩余系
POJ2773 Happy 2006
欧拉定理
欧拉定理推论
UVA106992 Huge Mods
HDU2837 Calculation
裴蜀定理
扩展欧几里得算法
POJ2115 Looooops
POJ1061 青蛙的约会
同余不等式
POJ3530 A Modular Arithmetic Challenge
线性同余方程组
中国剩余定理
非互质线性同余方程组
POJ2891 Strange Way to Express Integers
GCD Table
高次同余方程
BSGS算法
bzoj2242 [SDOI2011]计算器
原根与指标
例题代码
Prime Distance 代码
Counting Divisors代码
Combinations代码
余数之和代码
模积和代码
斐波那契公约数代码
GCD代码
Different GCD Subarray Query代码
Farey Sequence代码
Visible Lattice Points代码
Longge's problem代码
欧拉心算 代码
gcd代码
Sum Of Gcd代码
Happy 2006代码
Huge Mods代码
Calculation代码
Looooops代码
青蛙的约会代码
A Modular Arithmetic Challenge代码
Strange Way to Express Integers代码
GCD Table代码
[SDOI2011]计算器代码
若一个正整数 N 为合数,则一定存在一个能整除 N 的数字
大于2的素数n,存在,d为奇数
以下任一条件成立,n为素数,a为任意整数
typedef long long LL;
bool check(LL a, LL n) {
LL m = n - 1, x, y;
int i, j = 0;
while (~m & 1)m >>= 1, j++;
x = quickpow(a, m, n); //快速幂
for (i = 1; i <= j; x = y, i++) {
y = quickpow(x, 2, n);
if (y == 1 && x != 1 && x != n - 1)
return true;
}
return y != 1;
}
bool miller_rabin(int times, int n) {
LL a;
if (n == 1)return false;
if (n == 2) return true;
if (~n & 1)return false;
while (times--)
if (check(rand() % (n - 1) + 1, n))
return false;
return true;
}
任意x的倍数都不是素数
埃式筛法对同一个合数多次标记导致耗时非线性,比如
线性筛法通过唯一标记合数的方式来优化埃氏筛
for (int i = 2; i <= N; i++) {
if (!vis[i])prime[cnt++] = i;
for (int j = 0; j < cnt&&prime[j] * i <= N; j++) {
vis[prime[j] * i] = true;
if (i%prime[j] == 0)
break;
}
}
一个合数 n 一定包含一个不超过 的质因数
用筛法求出 以内的质数
用这些质数去标记 [L,R] 中的合数,未被标记的就是质数
const int maxm = 1000000;
bool v[maxm];
void interval_sieve(int l, int r) {
memset(v,0,sizeof(v));
if (l == 1)v[0] = true;
for (int i = 0; i < cnt; i++) {
for (int j = (l - 1) / prime[i] + 1; j <= r / prime[i]; j++) {
if (j > 1) v[prime[i] * j - l] = true;
}
}
}
给定整数L,R,求区间相邻两个质数的差最大是多少?
板子题
积性函数
因子数
则
本题要用到区间筛法对L-R分解质因数
求 Cm n (1 ≤n,m≤ 5∗105) 的不同质因子个数
分别求分子质因子个数和分母质因子个数,若分子个数比分母多则有效
约数个数
约数之和
给定正整数n,k,计算
当时,最多只有个取值
当时,最多只有个取值
综上最多只有个取值,且数值单调递减,可以数值分块
第一项与第二项与上题同
(a,b互质)
设 a = q∗b+r,其中 r = a mod b
对于 a,b 的任意公约数 d,d|a,d|q*b
则 d|(a-q*b),即 d|r
int gcd(int a,int b){
return b? gcd(b,a%b):a;}
}
当固定区间的右端点,区间左端点越小,区间的GCD就越小,区间GCD的变化次数至多等于右端点的质因子数
a1=1, a2=2, a3=4, a4=6
从小到大枚举右端点,计算左端点的分界线,表示对于右端点,左端点属于时区间gcd都是相同的
在枚举的过程中,可以利用右端点在时数组的计算结果,因为区间内多一个数字时,区间GCD的段数单调不增,可以通过右端点在时候的分段合并得到
a5=9
复杂度
//a[i]为数组
//l[j]表示l[j]-j的区间gcd相同
//v[j]表示l[j]-j的区间gcd的值
for (int i = 1; i <= n; i++) {
for (v[i] = a[i], j = l[i] = i; j; j = l[j] - 1) { //通过l[j]移动
v[j] = gcd(v[j], a[i]);
while (l[j] > 1 && gcd(a[i], v[j] - 1) == gcd(a[i], v[j])) //若两个区间gcd相同则合并
l[j] = l[l[j] - 1];
}
}
给出数组a,询问L,R的区间gcd的值和与L,R区间gcd相同的组数
枚举i的右端点,将所有的l[j]和v[j]分别存储(本题相同值的组数要开longlong!!!)
求L-R区间内区间gcd的值的数量
转化为求区间内颜色数量的问题,可以用离线树状数组或者主席树做,不会的可以看道例题学习下,洛谷 HH的项链
那么这题需要考虑的是怎么把区间的颜色转化到点上?
我们通过区间gcd可以知道L【j】- j的颜色,即只要包含右边界,就可以取到x
所以增加一个区间,相当于j点增加一种颜色
欧拉函数 ϕ(N):1 到 N 中与 N 互质的数字个数
对于质数p,
若a为质数,
大概意思应该是n的所有因数的欧拉函数和为n
分解质因数求欧拉函数
int phi(int n){
int ans=n;
for(int i=2;i*i<=n;i++){
if(n%i==0){
ans=ans/i*(i-1);
while(n%i==0) n/=i;
}
}
if(n>1) ans=ans/n*(n-1);
return ans;
}
线性筛求质因数
/*
特性 :
1.若a为质数,phi[a]=a-1;
2.若a为质数,b mod a=0,phi[a*b]=phi[b]*a
3.若a,b互质,phi[a*b]=phi[a]*phi[b](当a为质数时,if b mod a!=0 ,phi[a*b]=phi[a]*phi[b])
*/
bool vis[maxn+5];
int prime[maxn+5],cnt;
int phi[maxn+5];
void Phi() {
phi[1]=1;
vis[1]=true;
for(int i=2; i<=maxn; i++) {
if(!vis[i]) prime[cnt++]=i,phi[i]=i-1;
for(int j=0; j
求n以内的互质数对
欧拉函数求和,板子题
二维坐标站在(0,0)点上,能看到第一象限哪些点
看到的点的x,y都是互质的,考虑x,y轴和对角线
求
枚举GCD
因为x为N的因数,gcd(i,N)=x,i应与互质
欧拉函数是非完全积性函数,积性函数的约数和也是积性函数
若a为质数,b mod a=0,phi[a*b]=phi[b]*a
即若gcd(i,j)==x,则与互质
与上文中的Visible Lattice Points很像,即为二维坐标上互质的点,
同上题,取
求L和R,
一道RMQ问题,明显树状数组和线段树什么的无法维护,但可以用莫队做
那么我们只需要考虑莫队的转移就好
若d1----dn为n的所有因数,
设d1----dn为gcd(a[i],a[j])的因数,
比如2,4,有cnt[1]=2,cnt[2]=2,cnt[4]=1,因为约数1,2出现两次,1、2为公约数,phi[1]+phi[2]=2=gcd(2,4)
若已知cnt[d]=x,x中任选2个,可以成为gcd(a[i],a[j])的公约数
所以我们统计约数个数就能计算出a[j]与a[1]----a[j-1]的gcd之和
若,则称a,b模m同余
将相同的数归入一个集合,称为同余类
m 的 m 个同余类称为完全剩余系
所有与 m 互质的同余类称为简化剩余系
简化剩余系乘法封闭,若 a,b 分别和 m 互质,则 a*b 也 和 m 互质
求与n互质的第k小的数字
同理,
如题,若
以n为周期,求余,暴力第k小
若正整数 a,n 互质,有
若正整数a,p互质,则对于正整数b
当正整数 a,p 不一定互质时
欧拉降幂板子题
同上题
对于任意正整数a,b,存在一对整数x,y满足
证明裴蜀定理的过程求出了 x 和 y,这个计算方法称为扩展欧几里得算法
代码求出了 gcd(a,b),并得到了 ax+by=gcd(a,b) 的一组特 解,x 和 y 需要以引用方式传入
//ax1+ by1= gcd(a,b);
//bx2 + (a mod b)y2 = gcd(b, a mod b);
//ax1 + by1 = bx2 + (a - [a / b] * b)y2 = ay2 + bx2 - [a / b] * by2;
//x1 = y2; y1 = x2 - [a / b] * y2;
LL gcd(LL a, LL b, LL &x, LL & y)
{
if (b == 0) {
x = 1, y = 0;
return a;
}
int q = gcd(b, a%b, y, x);
y -= a / b * x;
return q;
}
求以下程序段的循环次数,其中变量为 k 位无符号整数
for (variable = A; variable != B; variable += C)
特解:
要
最小解:注意负数
简直和上一题一模一样
求x使得
y越小-->x越小
两边求余
两两互质,,
是线性同余方程的一个解
对于任意n个整数,方程组
for (int i = 1; i <= n; i++) {
M[i] = M / m[i];
d = gcd(m[i], M[i], x, y);
ans += y * m[i] * M[i];
}
以1、2两式为例
两边求余
,扩展欧几里得求解
将带会 式
且满足1,2两式
LL CRT() {
LL m1, m2, a1, a2, x, y, c;
m1 = m[1]; a1 = a[1];
bool flag = true;
for (int i = 2; i <= k; i++) {
m2 = m[i]; a2 = a[i];
c = exgcd(m1, m2, x, y);
if ((a2 - a1) % c)
flag = false;
x = (a2 - a1) / c * x;
y = m2 / c;
x = (x % y + y) % y;
a1 = x * m1 + a1;
m1 = (m1 * m2) / c;
}
c = exgcd(1, m1, x, y);
if (a1 % c) flag = false;
if (!flag)
return -1;
x = a1 / c * x;
y = m1 / c;
x = (x % y + y) % y;
return x;
}
板子题
题解链接
给定整数,求一个非负整数x,使得
设,其中是步长,这里取,
方程变为
即
将存入哈希表,枚举i,计算是否存在于哈希表中,即可更新答案
此处链接一位大神的博客
int bsgs(int a, int b, int p) {
map H;
H.clear();
b %= p;
int t = (int)sqrt(p) + 1;
for (int i = 0; i < t; i++) {
int val = (LL)b * quickpow(a, i, p) % p;
H[val] = i;
}
a = quickpow(a, t, p);
if (!a) return b ? -1 : 1;
for (int i = 0; i <= t; i++) {
int val = quickpow(a, i, p);
int j = H.find(val) == H.end() ? -1 : H[val];
if (j >= 0 && i * t >= j) return i * t - j;
}
return -1;
}
板子题
知识点链接
#include
#include
#include
#include
using namespace std;
const unsigned int max = 1 << 31;
const unsigned int maxn = 50000;
void io() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}
bool vis[maxn + 5];
unsigned int prime[maxn + 5], cnt = 0;
void Init() { //预处理<=R的素数
vis[1] = true;
for (int i = 2; i <= maxn; i++) {
if (!vis[i]) prime[cnt++] = i;
for (int j = 0; j < cnt && prime[j] * i <= maxn; j++) {
vis[prime[j] * i] = true;
if (i % prime[j] == 0)break;
}
}
}
const unsigned int maxm = 1000000;
bool v[maxm + 10];
void interval_sieve(unsigned int l, unsigned int r) { //区间筛
unsigned int limit = sqrt(r * 1.0) + 1;
if (l == 1)v[0] = true;
for (int i = 0; i < cnt; i++) {
if (prime[i] > limit) break;
for (int j = (l - 1) / prime[i] + 1; j <= r / prime[i]; j++) {
if (j > 1) v[prime[i] * j - l] = true;
}
}
}
int main() {
Init();
unsigned int l, r;
while (cin >> l >> r) {
interval_sieve(l, r);
unsigned int p = 0, a = 0, b = 0, c = 0, d = 0, min = r - l + 1, max = 0;
while (v[p])p++;
bool flag = false;
for (unsigned int i = p + 1; i <= r - l; i++) {
if (!v[i]) {
flag = true;
if (i - p < min)
a = p, b = i, min = i - p;
if (i - p > max)
c = p, d = i, max = i - p;
p = i;
}
}
if (!flag)printf("There are no adjacent primes.\n");
else printf("%d,%d are closest, %d,%d are most distant.\n", a + l, b + l, c + l, d + l);
fill(v, v + r - l + 10, 0);
}
}
#include
#include
#include
using namespace std;
typedef long long LL;
inline void io() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}
const LL mod = 998244353;
const int maxn = 1000010;
bool vis[maxn + 5];
int prime[maxn + 5], cnt = 0;
void Prime() {
vis[1] = true;
for (int i = 2; i <= maxn; i++) {
if (!vis[i])prime[cnt++] = i;
for (int j = 0; j < cnt && prime[j] * i <= maxn; j++) {
vis[prime[j] * i] = true;
if (prime[j] % i == 0)break;
}
}
}
LL k, num[maxn], d[maxn];
void slove(LL l, LL r) {
LL limit, g;
limit = sqrt(r * 1.0) + 1;
for (int i = 0; i < cnt; i++) {
if (prime[i] > limit)break;
LL s = (l + prime[i] - 1) / prime[i] * prime[i];
for (LL j = s; j <= r; j += prime[i]) { //用类似筛法的方法压缩时间
if (num[j - l] % prime[i] == 0) {
g = 0;
while (num[j - l] % prime[i] == 0) {
num[j - l] /= prime[i];
g++;
}
d[j - l] = d[j - l] * (k * g + 1) % mod;
}
}
}
}
int main() {
io(); Prime();
int t;cin >> t;
while (t--){
LL l, r;
cin >> l >> r >> k;
for (int i = 0; i <= r - l; i++)
num[i] = i + l, d[i] = 1;
slove(l, r);
LL ans = 0;
for (int i = 0; i <= r - l; i++) {
if (num[i] > 1) {
d[i] = d[i] * (k + 1) % mod;
}
ans += d[i]; ans %= mod;
}
cout << ans << '\n';
}
}
#include
#include
using namespace std;
const int maxn = 50005;
void io() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}
bool vis[maxn + 5];
int prime[maxn + 5], cnt;
void Prime() {
prime[1] = true;
for (int i = 2; i <= maxn; i++) {
if (!vis[i])prime[cnt++] = i;
for (int j = 0; j < cnt && prime[j] * i <= maxn; j++) {
vis[prime[j] * i] = true;
if (prime[j] % i == 0)break;
}
}
}
int GetNum(int N, int x) {
int res = 0, m = x;
while (N >= m) {
res += N / m;
m *= x;
}
return res;
}
int main() {
io(); Prime();
int n, m;
while (cin >> n >> m) {
int k = n - m, ans = 0, limit = n;
for (int i = 0; i < cnt; i++) {
if (prime[i] > limit)break;
if (GetNum(n, prime[i]) - GetNum(k, prime[i]) - GetNum(m, prime[i]) > 0)
ans++;
}
printf("%d\n", ans);
}
}
#include
#include
#include
using namespace std;
typedef long long LL;
void io() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
// k mod i= k - k / i * i
int main() {
io();
LL ans, n, k, r;
cin >> n >> k;
ans = n * k;
n = min(n, k);
for (LL l = 1; l <= n; l = r + 1) {
LL u = k / l;
r = min(k / u, n);
ans -= (l + r) * (r - l + 1) / 2 * u;
}
cout << ans << '\n';
}
#include
#include
#include
using namespace std;
typedef long long LL;
void io() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
LL mod = 19940417;
LL inv[8]; //求逆元
void init() {
inv[1] = 1;
for (LL i = 2; i <= 6; i++) {
inv[i] = (mod - mod / i) * (LL)1 * inv[mod % i] % mod;
}
}
// k mod i= k - k / i * i
LL GetNum(LL n) { //区间分块
LL ans = n * n % mod, r;
for (LL l = 1; l <= n; l = r + 1) {
LL u = n / l;
r = min(n / u, n);
ans = ans - (l + r) * (r - l + 1)/2 % mod * u % mod;
}
return ans % mod;
}
//sum(i,min(n,m))=(n*m-m*n/i*i-n*m/i*i+n/i*i*m/i*i)
int main() {
io(); init();
LL n, m, res;
cin >> n >> m;
res = GetNum(n) * GetNum(m) % mod;
if (n > m)swap(n, m);
LL cnt = n * m % mod * n % mod;
for (LL l = 1, r; l <= n; l = r + 1) {
r = min(n / (n / l), m / (m / l)); //选择较小的块移动
cnt += (n / l) * (m / l) % mod * ((r * (r + 1) % mod * (2 * r + 1) % mod * inv[6] % mod) - ((l - 1) * l % mod * (2 * l - 1) % mod * inv[6] % mod) + mod) % mod;
cnt -= m / l * n % mod * ((l + r) * (r - l + 1)/2 % mod); if (cnt < 0)cnt += mod;
cnt -= n / l * m % mod * ((l + r) * (r - l + 1)/2 % mod); if (cnt < 0)cnt += mod;
}
res -= cnt; res %= mod; if (res < 0)res+=mod;
cout << res << '\n';
}
#include
#include
using namespace std;
#pragma warning (disable:4996)
typedef long long int LL;
const LL mod = 1e8;
LL res[3][3] = { 0,0,0,0,1,1 }, r[3][3] = { 0,0,0,0,0,1,0,1,1 }, t[3][3];
LL gcd(LL a, LL b)
{
LL c;
while (c = a % b)
{
a = b;
b = c;
}
return b;
}
void mul(LL res[3][3], LL m[3][3], LL h)
{
for (int i = 1; i <= h; i++)
for (int j = 1; j <= 2; j++)
t[i][j] = (res[i][1] * m[1][j] % mod + res[i][2] * m[2][j] % mod) % mod;
for (int i = 1; i <= h; i++)
for (int j = 1; j <= 2; j++)
res[i][j] = t[i][j];
}
void quickmul(LL p)
{
while (p)
{
if (p & 1)
mul(res, r, 1);
mul(r, r, 2);
p >>= 1;
}
}
int main()
{
LL n, m;
scanf("%lld%lld", &n, &m);
LL cnt = gcd(n, m);
if (cnt == 1 || cnt == 2)
printf("1\n");
else
{
quickmul(gcd(n, m) - 2);
printf("%lld\n", res[1][2]);
}
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int maxn = 1000005;
bool vis[maxn + 5];
int prime[maxn + 5], cnt;
int phi[maxn + 5];
void Phi() {
phi[1] = 1;
vis[1] = true;
for (int i = 2; i <= maxn; i++) {
if (!vis[i]) prime[cnt++] = i, phi[i] = i - 1;
for (int j = 0; j < cnt && prime[j] * i <= maxn; j++) {
vis[prime[j] * i] = 1;
if (i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
}
LL sum[maxn+5];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
Phi(); phi[1] = 0;
for (int i = 1; i <= maxn; i++)
sum[i] = sum[i - 1] + phi[i];
int n;
while (cin>>n&&n)
cout << sum[n] << '\n';
}
#include
#include
#include
using namespace std;
typedef long long LL;
const int maxn = 1005;
bool vis[maxn + 5];
int prime[maxn + 5], cnt;
int phi[maxn + 5];
void Phi() {
phi[1] = 1;
vis[1] = true;
for (int i = 2; i <= maxn; i++) {
if (!vis[i]) prime[cnt++] = i, phi[i] = i - 1;
for (int j = 0; j < cnt && prime[j] * i <= maxn; j++) {
vis[prime[j] * i] = 1;
if (i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
}
int sum[maxn + 5];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
Phi(); phi[1] = 0;
for (int i = 1; i <= maxn; i++)
sum[i] = sum[i - 1] + phi[i];
int n, x, g = 0; cin >> n;
while (n--) {
cin >> x;
cout << ++g << ' ' << x << ' ' << 2 * sum[x] + 3<
//推导见数论博客
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int maxn = 47000;
bool vis[maxn + 5];
int prime[maxn + 5], cnt = 0;
void Prime() {
vis[1] = true;
for (int i = 2; i <= maxn; i++) {
if (!vis[i]) prime[cnt++] = i;
for (int j = 0; j < cnt && i * prime[j] <= maxn; j++) {
vis[prime[j] * i] = true;
if (i % prime[j] == 0)break;
}
}
}
void slove(int n) {
int limit = sqrt(n * 1.0) + 1;
LL ans = 1;
int m, g;
for (int i = 0; i < cnt; i++) {
if (prime[i] > limit) break;
if (n % prime[i] == 0) {
m = n; g = 0;
while (n % prime[i] == 0) {
n /= prime[i];
g++;
}
ans = ans * (LL(m) / n / prime[i] * g * (prime[i] - 1) + m / n);
}
}
if (n > 1) ans = ans * (LL(2) * n - 1);
cout << ans << '\n';
}
int main() {
Prime();
int n;
while (cin >> n)
slove(n);
}
#include
#include
#include
using namespace std;
typedef long long LL;
const int maxn = 10000005;
bool vis[maxn + 5];
int prime[maxn + 5], cnt;
int phi[maxn + 5];
LL sum[maxn + 5];
void Phi() {
phi[1] = 1;
vis[1] = true;
for (int i = 2; i <= maxn; i++) {
if (!vis[i]) prime[cnt++] = i, phi[i] = i - 1;
for (int j = 0; j < cnt && prime[j] * i <= maxn; j++) {
vis[prime[j] * i] = 1;
if (i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
for (int i = 1; i <= maxn; i++)
sum[i] = sum[i - 1] + phi[i];
}
//Sum(phi[x])*2*Sum(phi[n/x])-1)
void slove(int n) {
LL ans = 0;
for (int l = 1, r; l <= n; l = r + 1) {
int u = n / l;
r = n / u;
ans += (sum[r] - sum[l - 1]) * (sum[u] * 2 - 1);
}
cout << ans << '\n';
}
int main() {
Phi();
int t, n;
cin >> t;
while (t--){
cin >> n;
slove(n);
}
}
#include
#include
#include
using namespace std;
typedef long long LL;
const int maxn = 1000005;
const LL mod = 1e9 + 7;
bool vis[maxn + 5];
int prime[maxn + 5], cnt;
int phi[maxn + 5];
LL sum[maxn + 5];
void Phi() {
phi[1] = 1;
vis[1] = true;
for (int i = 2; i <= maxn; i++) {
if (!vis[i]) prime[cnt++] = i, phi[i] = i - 1;
for (int j = 0; j < cnt && prime[j] * i <= maxn; j++) {
vis[prime[j] * i] = 1;
if (i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
for (int i = 1; i <= maxn; i++) {
sum[i] = sum[i - 1] + phi[i];
sum[i] %= mod;
}
}
LL quickpow(LL x,LL k) {
LL res = 1, m = x;
while(k){
if (k & 1) res *= m, res %= mod;
m *= m; m %= mod;
k >>= 1;
}
return res;
}
LL GetSum(LL x, LL l, LL r) {
LL inv = quickpow(x - 1, mod - 2);
LL ans = quickpow(x, l) * ((quickpow(x, r - l + 1) - 1 + mod) % mod) % mod * inv % mod;
ans = ans - (r - l + 1) + mod; ans %= mod;
return ans;
}
//Sum(x^k-1)*2*Sum(phi[n/x])-1)
void slove(LL x, LL n) {
LL ans = 0;
for (LL l = 1, r; l <= n; l = r + 1) {
LL u = n / l;
r = n / u;
ans += GetSum(x, l, r) * ((sum[u] * 2 - 1) % mod) % mod;
ans %= mod;
}
cout << ans << '\n';
}
int main() {
Phi();
int t, n, x;
cin >> t;
while (t--) {
cin >> x >> n;
if (x == 1) {
cout << "0\n";
continue;
}
slove(x, n);
}
}
#include
#include
#include
#include
#include
#include
using namespace std;
#pragma warning (disable:4996)
typedef long long LL;
const int maxn = 20005;
int E[maxn + 5][233];
void Init() {
int cnt;
for (int i = 1; i < maxn; i++) {
cnt = 0;
for (int j = 1; j * j <= i; j++) {
if (i % j == 0) {
E[i][++cnt] = j;
if (j * j != i)
E[i][++cnt] = i / j;
}
}
E[i][0] = cnt;
}
}
bool vis[maxn + 5];
int prime[maxn + 5], cnt;
int phi[maxn + 5];
void Phi() {
phi[1] = 1;
vis[1] = true;
for (int i = 2; i <= maxn; i++) {
if (!vis[i]) prime[cnt++] = i, phi[i] = i - 1;
for (int j = 0; j < cnt && prime[j] * i <= maxn; j++) {
vis[prime[j] * i] = 1;
if (i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
}
int a[maxn], ops[maxn];
LL res[maxn];
struct Node {
int id;
int left;
int right;
bool operator <(const Node& a)const{
if (ops[left] == ops[a.left])
return right < a.right;
return ops[left] < ops[a.left];
}
} q[maxn];
LL num[maxn];
int main() {
Init();
Phi();
int t, n, m, g = 0;
cin >> t;
while (t--) {
printf("Case #%d:\n", ++g);
scanf("%d", &n);
int Size = (int)sqrt(n * 1.0);
for (int i = 1; i <= n; i++)scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)ops[i] = i / Size;
scanf("%d", &m);
for (int i = 1; i <= m; i++){
scanf("%d%d", &q[i].left, &q[i].right);
q[i].id = i;
}
sort(q + 1, q + 1 + m);
int stdl = 1, stdr = 0;
LL ans = 0; int d;
for (int i = 1; i <= m; i++){
while (stdl > q[i].left){
stdl--;
for (int j = 1; j <= E[a[stdl]][0]; j++) {
d = E[a[stdl]][j];
num[d]++;
ans += (num[d] - 1) * phi[d];
}
}
while (stdr < q[i].right){
stdr++;
for (int j = 1; j <= E[a[stdr]][0]; j++) {
d = E[a[stdr]][j];
num[d]++;
ans += (num[d] - 1) * phi[d];
}
}
while (stdl < q[i].left){
for (int j = 1; j <= E[a[stdl]][0]; j++) {
d = E[a[stdl]][j];
ans -= (num[d] - 1) * phi[d];
num[d]--;
}
stdl++;
}
while (stdr > q[i].right){
for (int j = 1; j <= E[a[stdr]][0]; j++) {
d = E[a[stdr]][j];
ans -= (num[d] - 1) * phi[d];
num[d]--;
}
stdr--;
}
res[q[i].id] = ans;
}
for (int i = 1; i <= m; i++)
printf("%lld\n", res[i]);
memset(num, 0, sizeof(num));
}
}
#include
#include
#include
using namespace std;
#pragma warning (disable:4996)
typedef long long LL;
int Phi(int n) {
int ans = n;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
ans = ans / i * (i - 1);
while (n % i == 0) n /= i;
}
}
if (n > 1) ans = ans / n * (n - 1);
return ans;
}
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
int main() {
int n, k, phi;
while (~scanf("%d%d", &n, &k)) {
phi = Phi(n);
LL ans = LL(k - 1) / phi * n;
k %= phi;
if (k == 0)k = phi;
for (int i = 1; i <= n; i++) {
if (gcd(i, n) == 1)
k--;
if (k == 0) {
ans += LL(i);
break;
}
}
printf("%lld\n", ans);
}
}
#include
#include
#include
using namespace std;
#pragma warning (disable:4996)
typedef long long int LL;
int Phi(int n) {
int ans = n;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
ans = ans / i * (i - 1);
while (n % i == 0) n /= i;
}
}
if (n > 1) ans = ans / n * (n - 1);
return ans;
}
int mod, k;
int a[30];
int quickpow(LL m, LL p, LL mod) {
LL res = 1, f1 = 0, f2 = 0;
while (p) {
if (p & 1) {
f1 |= (res * m >= mod || f2);
res *= m; res %= mod;
}
f2 |= (m * m >= mod);
m *= m; m %= mod;
p >>= 1;
}
return res + f1 * mod;
}
int slove(int x, int mod) {
if (x == k) return quickpow(a[x], 1, mod);
return quickpow(a[x], slove(x + 1, Phi(mod)), mod);
}
int main() {
int g = 0;
while (cin >> mod) {
if (mod == '#')break;
cin >> k;
for (int i = 1; i <= k; i++) cin >> a[i];
printf("Case #%d: %d\n", ++g, slove(1, mod) % mod);
}
}
#include
#include
#include
using namespace std;
#pragma warning (disable:4996)
typedef long long int LL;
LL Phi(LL n) {
LL ans = n;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
ans = ans / i * (i - 1);
while (n % i == 0) n /= i;
}
}
if (n > 1) ans = ans / n * (n - 1);
return ans;
}
LL quickpow(LL m, LL p, LL mod) {
LL res = 1, f1 = 0, f2 = 0;
while (p) {
if (p & 1) {
f1 |= (res * m >= mod || f2);
res *= m; res %= mod;
}
f2 |= (m * m >= mod);
m *= m; m %= mod;
p >>= 1;
}
return res + f1 * mod;
}
LL n, m;
//f(n) = (n % 10) ^ f(n / 10)
LL slove(LL x, LL mod) {
if (x == 0) return 1;
return quickpow(x % 10, slove(x / 10, Phi(mod)), mod);
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%lld%lld", &n, &m);
printf("%lld\n", slove(n, m) % m);
}
}
#include
#include
using namespace std;
#pragma warning (disable:4996)
typedef long long LL;
LL in2[35];
void Init() {
for (int i = 1; i <= 34; i++)
in2[i] = LL(1) << i;
}
LL gcd(LL a, LL b, LL& x, LL& y)
{
if (b == 0) {
x = 1, y = 0;
return a;
}
int q = gcd(b, a % b, y, x);
y -= a / b * x;
return q;
}
int main() {
Init();
LL a, b, c, k;
while (cin >> a >> b >> c >> k && a + b + c + k) {
LL x, y;
LL d = gcd(c, in2[k], x, y);
if ((b - a) % d == 0) {
LL ans = x * (b - a) / d % in2[k];
printf("%lld\n", (ans % (in2[k] / d) + in2[k] / d) % (in2[k] / d));
}
else
printf("FOREVER\n");
}
}
#include
#include
using namespace std;
#pragma warning (disable:4996)
typedef long long LL;
LL in2[35];
void Init() {
for (int i = 1; i <= 34; i++)
in2[i] = LL(1) << i;
}
LL gcd(LL a, LL b, LL& x, LL& y)
{
if (b == 0) {
x = 1, y = 0;
return a;
}
int q = gcd(b, a % b, y, x);
y -= a / b * x;
return q;
}
int main() {
LL a, b, m, n, L, x, y;
cin >> a >> b >> m >> n >> L;
LL c = a - b;
a = n - m;
LL d = gcd(a, L, x, y);
if (c % d == 0) {
LL ans = x * c / d;
ans %= (L / d);
if (ans < 0)ans += L / d;
printf("%lld\n", ans);
}
else
printf("Impossible\n");
}
#include
#include
#include
using namespace std;
#pragma warning (disable:4996)
typedef long long LL;
LL slove(LL M, LL D, LL L, LL R) {
if (L > R || D == 0) return -1;
if (R / D * D >= L) return (L + D - 1) / D;
LL l = (-L) % D; if (l < 0) l += D;
LL r = (-R) % D; if (r < 0) r += D;
LL x = slove(D, M % D, r, l);
if (x == -1)return -1;
return (L + x * M + D - 1) / D;
}
int main() {
LL D, M, L, R, t;
cin >> t;
while (t--) {
cin >> M >> D >> L >> R;
R = min(M - 1, R);
cout << slove(M, D, L, R) << '\n';
}
}
#include
#include
#include
using namespace std;
#pragma warning (disable:4996)
typedef long long LL;
LL gcd(LL a, LL b, LL& x, LL& y)
{
if (b == 0) {
x = 1;
y = 0;
return a;
}
LL q = gcd(b, a % b, y, x);
y -= a / b * x;
return q;
}
int main() {
LL k, m1, m2, a1, a2, x, y, c;
while (~scanf("%lld", &k)) {
scanf("%lld%lld", &m1, &a1);
bool flag = true;
k--;
while (k--) {
scanf("%lld%lld", &m2, &a2);
c = gcd(m1, m2, x, y);
if ((a2 - a1) % c) flag = false;
if(flag){
x = (a2 - a1) / c * x;
y = m2 / c;
x = (x % y + y) % y;
a1 = x * m1 + a1;
m1 = (m1 * m2) / c;
}
}
c = gcd(1, m1, x, y);
if (a1 % c) flag = false;
if(!flag) printf("-1\n");
else {
x = a1 / c * x;
y = m1 / c;
x = (x % y + y) % y;
printf("%lld\n", x);
}
}
}
#include
#include
#include
using namespace std;
#pragma warning (disable:4996)
typedef long long LL;
LL gcd(LL a, LL b) {
return b == 0 ? a : gcd(b, a % b);
}
LL lcm(LL a, LL b) {
return a / gcd(a, b) * b;
}
LL exgcd(LL a, LL b, LL& x, LL& y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
LL q = exgcd(b, a % b, y, x);
y -= a / b * x;
return q;
}
LL mul(LL x, LL p, LL mod) {
if (p < 0) x = -x, p = -p;
LL ret = 0;
for (; p; p >>= 1, x = (x + x) % mod) if (p & 1) ret = (ret + x) % mod;
return ret;
}
LL _x, _y, k;
LL m[10005], a[10005];
LL CRT() {
LL m1, m2, a1, a2, x, y, c;
m1 = m[1];
a1 = a[1];
bool flag = true;
for (int i = 2; i <= k; i++) {
m2 = m[i];
a2 = a[i];
c = exgcd(m1, m2, x, y);
if ((a2 - a1) % c)
flag = false;
y = m2 / c;
x = mul((a2 - a1) / c, x, y);
x = (x % y + y) % y;
a1 = x * m1 + a1;
m1 = (m1 * m2) / c;
}
c = exgcd(1, m1, x, y);
if (a1 % c) flag = false;
if (!flag)
return -1;
x = a1 / c * x;
y = m1 / c;
x = (x % y + y) % y;
return x == 0 ? y : x;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> _x >> _y >> k;
LL Lcm = 1;
for (int i = 1; i <= k; i++) {
cin >> m[i];
Lcm = lcm(Lcm, m[i]);
if (Lcm > _x) {
printf("NO\n");
return 0;
}
a[i] = ((m[i] - i + 1) % m[i] + m[i]) % m[i];
}
LL ans = CRT();
if (ans == -1 || ans + k - 1 > _y) {
printf("NO\n");
return 0;
}
for (int i = 1; i <= k; i++) {
if (gcd(Lcm, ans + i - 1) != m[i]) {
printf("NO\n");
return 0;
}
}
printf("YES\n");
}
#include
#include
#include