[ L i n k \frak{Link} Link]
我建议去洛谷看题面((
就是说 x n ≡ a n x 0 + ∑ i = 0 n − 1 a i c ( m o d m ) x_n\equiv a^nx_0+\sum\limits_{i=0}^{n-1}a^ic\pmod{m} xn≡anx0+i=0∑n−1aic(modm)
感觉可以直接球?? x n = ( a n x 0 + ∑ i = 0 n − 1 a i c ) % m = [ ( a n x 0 ) + ( a n − 1 ) c a − 1 ] % m x_n=(a^nx_0+\sum\limits_{i=0}^{n-1}a^ic)\%m=\left[(a^nx_0)+\frac{(a^n-1)c}{a-1}\right]\%m xn=(anx0+i=0∑n−1aic)%m=[(anx0)+a−1(an−1)c]%m
快速幂 a n a^n an ,然后逆元就可以啦。是吗?
这个逆元不一定存在吧。所以要暴力分治做等比数列求和 + 取模。
注意最后要输出 x n % g x_n\%g xn%g 。
注意: x % a % b x\%a\%b x%a%b 并不总是等于 x % b % a x\%b\%a x%b%a 。也就是说不能快乐全程 % g % m \%g\%m %g%m
计算 x n x_n xn 的时候只能 % m \%m %m ,计算出来了才能 % g \%g %g 。
这就带来了一个问题,这样爆 long long 很大力啊?
解决方法:用龟速乘法,类似于快速幂那样拆乘法取模。。。
当然,也可以用矩阵快速幂加速递推……随意啦。反正挺沙雕的。
我怎么感觉 BZOJ 评测比洛谷快了x
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
unsigned long long m, a, c, x, n, g, t;
unsigned long long mul(unsigned long long a, unsigned long long b)
{
unsigned long long ret = 0;
while(b)
{
if (b & 1)
{
ret += a;
ret %= m;
}
a += a;
a %= m;
b >>= 1;
}
return ret;
}
unsigned long long qpow(unsigned long long base, unsigned long long ind)
{
base %= m;
unsigned long long ans = 1;
while (ind)
{
if (ind & 1)
{
ans = mul(ans, base);
}
base = mul(base, base);
ind >>= 1;
}
return ans;
}
unsigned long long qsum(long long N)
{
if (N <= 1) return 1;
unsigned long long fafa = mul(qsum(N >> 1), (qpow(a, N >> 1) + 1));
if (N & 1 == 1) fafa += qpow(a, N - 1);
return fafa % m;
}
int main()
{
scanf("%lld%lld%lld%lld%lld%lld", &m, &a, &c, &x, &n, &g);
t = mul(qpow(a, n), x) % m;
t += mul(qsum(n), c) % m;
printf("%lld", t % m % g);
return 0;
}
后面是我这个菜鸡补小学奥数的一点记录(
与这道大氵题无关。
费马小定理:对于质数 p p p 和整数 a < p a<p a<p 有 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1\pmod{p} ap−1≡1(modp)
证明:构建 p p p 的完全剩余系 P = { 1 , 2 , ⋯   , p − 1 } P=\{1,2,\cdots,p-1\} P={1,2,⋯,p−1} 又 ( a , p ) = 1 (a,p)=1 (a,p)=1
那么 A = { a , 2 a , ⋯   , ( p − 1 ) a } A=\{a,2a,\cdots,(p-1)a\} A={a,2a,⋯,(p−1)a} 也是 p p p 的完全剩余系。
所以 ( p − 1 ) ! ≡ ( p − 1 ) ! a p − 1 ( m o d p ) (p-1)!\equiv(p-1)!a^{p-1}\pmod{p} (p−1)!≡(p−1)!ap−1(modp) ,又 ( ( p − 1 ) ! , p ) = 1 \left((p-1)!,p\right)=1 ((p−1)!,p)=1 显然可以得证。
同时,不论 a a a 是否小于 p p p 都有 a p ≡ a ( m o d p ) a^p\equiv a\pmod{p} ap≡a(modp)
利用这个可以求整数 a < p a<p a<p 在模质数 p p p 意义下的逆元 a p − 2 ( m o d p ) a^{p-2}\pmod{p} ap−2(modp)
贝祖定理:
一个重要推论: ∃ a , b , a x + b y = 1 \exists a,b,ax+by=1 ∃a,b,ax+by=1 是 ( a , b ) = 1 (a,b)=1 (a,b)=1 的充要条件。
GCD:当 a a a ≠ k b , k ∈ N ∗ kb,k\in\N^* kb,k∈N∗ 时 ( a , b ) = ( a % b , b ) (a,b)=(a\%b,b) (a,b)=(a%b,b) 。以及一段代码 !b?a:gcd(b,a%b)
为什么代码里面要 b,a%b
?
因为如果写成 a%b,b
,当 a < b a<b a<b 时就可能无限循环了。交换一下就可以解决。
证明:显然有 ( a , b ) ∣ b (a,b)|b (a,b)∣b 没错吧??
先假设 a > b a>b a>b
我们设 a = k b + r a=kb+r a=kb+r ,
因为 ( a , b ) ∣ k b (a,b)|kb (a,b)∣kb 而且 ( a , b ) ∣ a (a,b)|a (a,b)∣a
那么 ( a , b ) ∣ k b (a,b)|kb (a,b)∣kb 而且 ( a , b ) ∣ ( k b + r ) (a,b)|(kb+r) (a,b)∣(kb+r)
显然 ( a , b ) ∣ r (a,b)|r (a,b)∣r
而且 r = a % b r=a\%b r=a%b 显然啦。
ExGCD: ( a , b ) = a x + b y (a,b)=ax+by (a,b)=ax+by 然后我们求 x x x 和 y y y
b = 0 b=0 b=0 时 x = 1 , y = 0 x=1,y=0 x=1,y=0 。这个特殊情况不能用。
b b b ≠ 0 0 0,我们仍然假设 a > b a>b a>b 。对于每次 ( a , b ) (a,b) (a,b) 到 ( b , a % b ) (b,a\%b) (b,a%b) 过程中 x , y x,y x,y 的变化:
设 a x 1 + b y 1 = ( a , b ) = ( b , a % b ) = b x 2 + ( a % b ) y 2 ax_1+by_1=(a,b)=(b,a\%b)=bx_2+(a\%b)y_2 ax1+by1=(a,b)=(b,a%b)=bx2+(a%b)y2
设 a = k b + r a=kb+r a=kb+r 。有 a x 1 + b y 1 = b x 2 + ( a − k b ) y 2 ax_1+by_1=bx_2+(a-kb)y_2 ax1+by1=bx2+(a−kb)y2
我们记 a / b = ⌊ a b ⌋ a/b=\lfloor\frac{a}{b}\rfloor a/b=⌊ba⌋ 那么 a x 1 + b y 1 = b x 2 + a y 2 − ( a / b ) ⋅ b y 2 ax_1+by_1=bx_2+ay_2-(a/b)\cdot by_2 ax1+by1=bx2+ay2−(a/b)⋅by2
a x 1 + b y 1 = a y 2 + b [ x 2 − ( a / b ) y 2 ] ax_1+by_1=ay_2+b[x_2-(a/b)y_2] ax1+by1=ay2+b[x2−(a/b)y2] 所以 x 1 = y 2 , y 1 = [ x 2 − ( a / b ) y 2 ] x_1=y_2,y_1=[x_2-(a/b)y_2] x1=y2,y1=[x2−(a/b)y2]
这样的话就可以从 b = 0 b=0 b=0 的时候开始一路倒推直到 a , b a,b a,b 都是原来的样子。
就可以得到原方程 a x + b y = ( a , b ) ax+by=(a,b) ax+by=(a,b) 的一组解。
ExGCD 解不定方程 a x + b y = c ax+by=c ax+by=c :
显然 ( a , b ) ∣ c (a,b)|c (a,b)∣c 才有解。
否则……那不就随便解解嘛,不讲了?细节自己草稿纸吧。
也需要稍微说一下通解的形式:设 r = ( a , b ) r=(a,b) r=(a,b) ,对于 a x + b y = r ax+by=r ax+by=r 如果有一组解 x 0 , y 0 x_0,y_0 x0,y0
显然 a ⋅ [ x ± ( b / r ) ] + b ⋅ [ y ∓ ( a / r ) ] = r a\cdot[x\pm (b/r)]+b\cdot[y\mp(a/r)]=r a⋅[x±(b/r)]+b⋅[y∓(a/r)]=r
于是通解的形式是 x = x 0 ± b / r , y = y 0 ∓ ( a / r ) x=x_0\pm b/r,y=y_0\mp(a/r) x=x0±b/r,y=y0∓(a/r) 。
启发这个想法的是把 x 0 , y 0 x_0,y_0 x0,y0 改动后保持等价,显然可以凑 a ( x 0 + b ) + b ( y 0 − a ) = r a(x_0+b)+b(y_0-a)=r a(x0+b)+b(y0−a)=r
要在保证 x , y x,y x,y 是整数的前提下表示出尽量多的解,所以就变成 b / r b/r b/r 和 a / r a/r a/r 啦。
ExGCD 解线性同余方程 a x ≡ c ( m o d b ) ax\equiv c\pmod{b} ax≡c(modb)
转化: a x % b = c % b ax\%b=c\%b ax%b=c%b
转化化: a x + b μ = c + b λ ax+b\mu=c+b\lambda ax+bμ=c+bλ
转化化化: a x + b y = c ax+by=c ax+by=c
解出 x 0 x_0 x0 ,设 s = b / r s=b/r s=b/r ,然后最小正整数解 ( x 0 % s + s ) % s (x_0\%s+s)\%s (x0%s+s)%s
为什么最小整数解是这个?……你认真的?
……里面模一次,得到的不一定是正数,加上 s s s 再模一次得到正数。
PS:C艹的取模是向零取整的,无论正负。
ExGCD求逆元
就是上面那个啊。