数论(updating)
1、整除
“真”例题:洛谷3518
题解:首先结合裴蜀定理得出gcd(x,n)和gcd(x,y)均为密码,然后即可得出所有密码为x的1至n/x倍(x为gcd(a[k],n)的最小的不整除a[1]~a[k-1]的因子),因为因子数不多可以暴力筛选,ans=n/x。
1 #include <bits/stdc++.h> 2 #define int long long 3 4 using namespace std; 5 6 const int len = 3e5; 7 int n,k,ans,a[len]; 8 9 inline bool cmp(int x) { 10 for (int i=1;i<k;i++) if (a[i]%x == 0) return false; 11 return true; 12 } 13 14 signed main() { 15 ios :: sync_with_stdio(0); 16 cin >> n >> k; 17 for (int i=1;i<=k;i++) cin >> a[i]; 18 a[k] = __gcd(a[k],n); 19 for (int i=1;i*i<=a[k];i++) { 20 if (a[k]%i==0 && cmp(i)) { 21 cout << n/i << endl; 22 return 0; 23 } 24 else if (a[k]%i==0 && cmp(a[k]/i)) { 25 ans = n/(a[k]/i); 26 } 27 } 28 cout << ans << endl; 29 return 0; 30 }
2、真·同余线性筛素数
例题:poj3292
题解:变化版的线性筛
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int M = 1e6+11; 8 int n,q,cnt; 9 int h[M],s[M],p[M],ans[M]; 10 11 inline void pre_H() { 12 n = 0; 13 for (int i=5;i<=M;i++) { 14 if ((i-1)%4 == 0) h[++n] = i; 15 } 16 return; 17 } 18 19 inline void init() { 20 cnt = 0; 21 for (int i=1;i<=n;i++) { 22 if (!s[h[i]]) s[h[i]] = 1,p[++cnt] = h[i]; 23 for (int j=1;j<=cnt && h[i]*p[j]<M;j++) { 24 s[h[i]*p[j]] = s[h[i]]+1; 25 if (h[i]%p[j] == 0) break; 26 } 27 } 28 for (int i=5;i<M;i++) { 29 ans[i] = ans[i-1]; 30 if (s[i] == 2) ans[i]++; 31 } 32 return; 33 } 34 35 int main() { 36 pre_H(); 37 init(); 38 while (scanf("%d",&q) && q!=0) printf("%d %d\n",q,ans[q]); 39 return 0; 40 }
3、同余
例题:洛谷1290
题解:找规律后可以发现,对于任意一种初始局面(即所需取数次数)不为1的情况先手有必胜策略(中间即使出现1先手也可以通过一定的取数策略达到此状态),故只需要考虑一开始连续为1的情况即可
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int c,n,m; 6 7 int main() { 8 ios :: sync_with_stdio(0); 9 cin >> c; 10 while (c--) { 11 cin >> m >> n; 12 if (m < n) swap(m,n); 13 if (m%n == 0) { 14 cout << "Stan wins" << endl; 15 continue; 16 } 17 int f = 1; 18 while (m/n == 1) { 19 f = -f; 20 int k = n; 21 n = m%n,m = k; 22 } 23 if (f == 1) cout << "Stan wins" << endl; 24 else cout << "Ollie wins" << endl; 25 } 26 return 0; 27 }
4、扩展欧几里得
例题:poj1061
题解:化出(m-n)x + Ly = y-x这个式子后直接大力exgcd
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #define int long long 6 7 using namespace std; 8 9 int x,y,m,n,l,x_1,y_1; 10 int a,b,c,ans; 11 12 inline int exgcd(int a,int b,int &x1,int &y1) { 13 if (!b) { 14 x1 = 1,y1 = 0; 15 return a; 16 } 17 int gcd = exgcd(b,a%b,x1,y1); 18 int tmp = y1; 19 y1 = x1-a/b*y1,x1 = tmp; 20 return gcd; 21 } 22 23 inline void work() { 24 int ret = exgcd(a,b,x_1,y_1); 25 x_1 = x_1*c/ret; 26 int t = fabs(b/ret); 27 x_1 = (x_1%t+t)%t; 28 } 29 30 signed main() { 31 cin >> x >> y >> m >> n >> l; 32 if (x == y) { 33 cout << 0 << endl;return 0; 34 } 35 a = m-n,b = l,c = y-x; 36 if (c%__gcd(a,b) != 0) cout << "Impossible" << endl; 37 else work(),cout << x_1 << endl; 38 return 0; 39 }
5、pollard_rho
不说废话,上板子
1 #include <bits/stdc++.h> 2 #define int long long 3 4 using namespace std; 5 6 const int maxn = 10010; 7 int n,cnt,f[maxn]; 8 9 inline int qm(int n,int m,int mo) { 10 int ans = 0; 11 while (m) { 12 if (m&1) ans = (ans+n)%mo; 13 m >>= 1,n = (n+n)%mo; 14 } 15 return ans; 16 } 17 18 inline int qp(int n,int m,int mo) { 19 int ans = 1; 20 while (m) { 21 if (m&1) ans = qm(ans,n,mo); 22 m >>= 1,n = qm(n,n,mo); 23 } 24 return ans; 25 } 26 27 inline bool mr(int n) { 28 for (int i=1;i<=10;i++) { 29 int a = rand()%(n-1)+1; 30 int m = n-1; 31 if (qp(a,m,n) != 1) return false; 32 } 33 return true; 34 } 35 36 inline int pho(int n,int c) { 37 int i = 1,k = 2; 38 int x = rand()%(n-1)+1,y = x; 39 while (1) { 40 x = (qm(x,x,n)+c)%n; 41 int d = __gcd((y-x+n)%n,n); 42 if (d>1 && d<n) return d; 43 if (y == x) return n; 44 if (i == k) { 45 k <<= 1; 46 y = x; 47 } 48 } 49 } 50 51 inline void find(int n,int c) { 52 if (mr(n)) { 53 f[++cnt] = n; 54 return; 55 } 56 int p = n,k = c; 57 while (p >= n) p = pho(n,c--); 58 find(p,k),find(n/p,k); 59 } 60 61 signed main() { 62 ios :: sync_with_stdio(0); 63 srand(time(NULL)); 64 cnt = 0; 65 cin >> n; 66 find(n,1010); 67 sort(f+1,f+cnt+1); 68 for (int i=1;i<=cnt;i++) cout << f[i] << endl; 69 return 0; 70 }

浙公网安备 33010602011771号