HDU 6189
题目大意:给定 n n n和 a a a,令 m = 2 n m=2^n m=2n,求 b ∈ [ 1 , m ] b\in[1,m] b∈[1,m]且满足 a b ≡ b a ( m o d a^b≡b^a(mod ab≡ba(mod m ) m) m)的 b b b个数
打表可以得出当
a
a
a为奇数时,
s
u
m
=
1
sum=1
sum=1
当
a
a
a为偶数时,
a
b
a^b
ab为偶数,又因为
m
m
m为偶数,所以
a
b
%
m
a^b\%m
ab%m也是偶数,
a
b
%
m
=
b
a
%
m
a^b\%m=b^a\%m
ab%m=ba%m,同理
b
b
b为偶数
令
a
=
2
∗
x
a=2*x
a=2∗x,
a
b
%
m
=
2
b
∗
x
b
%
m
a^b\%m=2^b*x^b\%m
ab%m=2b∗xb%m,即
a
b
%
m
=
2
b
∗
x
b
%
2
n
a^b\%m=2^b*x^b\%2^n
ab%m=2b∗xb%2n
当
b
≤
n
b\leq n
b≤n时,因为
n
≤
30
n\leq 30
n≤30,暴力即可
当
b
>
n
b>n
b>n时,
2
b
∗
x
b
%
2
n
=
0
2^b*x^b\%2^n=0
2b∗xb%2n=0,即
a
b
%
m
=
0
a^b\%m=0
ab%m=0,即
b
a
%
m
=
0
b^a\%m=0
ba%m=0,现在就是求使
b
a
%
m
=
0
b^a\%m=0
ba%m=0成立的
b
b
b的个数
因为
b
b
b为偶数,
b
=
2
x
∗
y
b=2^x*y
b=2x∗y,令
c
=
y
a
c=y^a
c=ya,即
2
a
x
∗
c
%
2
n
=
0
2^{ax}*c\%2^n=0
2ax∗c%2n=0,当
a
x
≥
n
ax\geq n
ax≥n时,恒成立,即
x
≥
⌈
n
a
⌉
x\geq \lceil \frac{n}{a} \rceil
x≥⌈an⌉,令
x
=
⌈
n
a
⌉
x=\lceil \frac{n}{a} \rceil
x=⌈an⌉,此时
b
=
2
⌈
n
a
⌉
∗
y
b=2^{\lceil \frac{n}{a} \rceil}*y
b=2⌈an⌉∗y,符合
b
a
%
m
=
0
b^a\%m=0
ba%m=0,且当
y
=
1
y=1
y=1时,
b
b
b最小,现在从
(
n
,
m
]
(n,m]
(n,m]中查找
2
⌈
n
a
⌉
∣
b
2^{\lceil \frac{n}{a} \rceil}|b
2⌈an⌉∣b的个数,即
(
m
>
>
x
)
−
(
n
>
>
x
)
(m>>x)-(n>>x)
(m>>x)−(n>>x),为什么会这样呢,其实就是找
y
m
a
x
−
y
m
i
n
y_{max}-y_{min}
ymax−ymin,即
⌈
m
2
x
⌉
−
⌈
n
2
x
⌉
\lceil\frac{m}{2^x}\rceil-\lceil\frac{n}{2^x}\rceil
⌈2xm⌉−⌈2xn⌉……
唉,好累……
//#include <bits/stdc++.h>
#include <iostream>
#define IOS ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const int INF = 0x7f7f7f7f;
const int MAXN = 105;
ll quickpow(ll a, ll b, int mod) {
if (!b) return 1 % mod;
ll ans = 1;
while (b) {
if (b & 1)
ans = ans * a % mod;
b >>= 1;
a = a * a % mod;
}
return ans;
}
int main() {
IOS;
ll a, n;
while (~scanf("%lld%lld", &n, &a)) {
ll sum = 0;
if (a & 1) {
cout << 1 << endl;
continue;
}
int m = 1 << n;
for (int b = 2; b <= n; b += 2) {
if (quickpow(a, b, m) == quickpow(b, a, m))
sum++;
}
int x = ceil(double(n) / a);
sum += (m >> x) - (n >> x);
cout << sum << endl;
}
return 0;
}
Happy Equation
2019icpc山东省省赛
和上面hdu的简直不要太一样
注意一点:快速幂里分步mod,不然会爆
https://zoj.pintia.cn/problem-sets/91827364500/problems/91827370518
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const int INF = 0x7f7f7f7f;
const int MAXN = 105;
ll quickpow(ll a, ll b, int mod) {
if (!b) return 1 % mod;
ll ans = 1;
while (b) {
if (b & 1)
ans = ans * a % mod;
b >>= 1;
a = (a % mod * a % mod) % mod;
}
return ans;
}
int main() {
IOS;
int T;
cin >> T;
while (T--) {
ll a, p;
cin >> a >> p;
ll sum = 0;
if (a & 1) {
cout << 1 << endl;
continue;
}
int m = 1 << p;
for (int b = 2; b <= p; b += 2) {
if (quickpow(a, b, m) == quickpow(b, a, m))
sum++;
}
int x = ceil(double(p) / a);
sum += (m >> x) - (p >> x);
cout << sum << endl;
}
return 0;
}