题解有空补,咕咕咕。
卡常科技:Binary Jacobi
前置知识:Binary gcd。
下文 (qp) 为 Jacobi 符号。
原理(部分证明)参见这里。
令 p 为正整数,a,b 为与 p 互素的整数,有结论:
-
乘法结合:(pa)×(pb)=(pab)
-
(p2)=(−1)8p2−1
-
二次互反律:当 p,q 为奇数且 (p,q)=1 时,(qp)×(pq)=(−1)4(p−1)(q−1)
欲求 (qp),其中 q 为奇数,p 为与 q 互素的任意数。
设 p=2mk,则 (qp)=(q2)m×(qk)=(−1)8m(q2−1)×(qk)。
用二次互反律:(qp)=(−1)8m(q2−1)×(−1)4(k−1)(q−1)×(kq)。
递归下去即可,复杂度类似 gcd 的复杂度,为 O(logV),但是常数极小,快速幂 30s 的这个 4s−。
#define mytz __builtin_ctzll
inline bool jac(ull a,ull b)
{
bool ans=0;
while(1)
{
a%=b;if(a==1) return ans;
short az=mytz(a),o=az&1&(((b*b-1)&15)!=0);a>>=az;
ans^=o;if(a==1) return ans;
ans^=((((a-1)*(b-1))&7)!=0);swap(a,b);
}return ans;
}
本题做法同大众做法,只是把素数增大了保证正确性,实测没有这个优化你根本过不去。
本题代码实现。