2022.1.14打卡
阿新 • • 發佈:2022-01-14
A-青蛙的約會_牛客競賽數學專題班整數分解與篩法 (nowcoder.com)
根據題意推出表示式,用擴充套件歐幾里得可解,注意處理大小寫
#include <bits/stdc++.h> #define fi first #define int long long #define se second #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef vector<int> vi; ll exgcd(ll a,ll b,ll &x,ll &y) { if (b==0) { x = 1, y = 0; return a; } ll c = exgcd(b,a%b,x,y); ll tx = x; x = y; y = tx - (a/b)*y; return c; } ll gcd(ll a,ll b) { if (a<b) swap(a,b); while (b>0) { ll t = a; a = b; b = t % b; } return a; } signed main() { ll x,y,m,n,L; cin>>x>>y>>m>>n>>L; ll a = L; ll b = n-m; ll c = x-y; if (b<0) { b = -b; c = -c; } ll d = gcd(a,b); // cout<<a<<" "<<b<<" "<<c<<" "<<d<<'\n'; if (c%d!=0) cout<<"Impossible"; else { exgcd(a,b,x,y); y = (c/d*y%(a/d)+(a/d))%(a/d); cout<<y; } }
B-Sum of Consecutive Prime Numbers_牛客競賽數學專題班整數分解與篩法 (nowcoder.com)
處理出素數用尺取法
#include <bits/stdc++.h> #define fi first #define se second #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef vector<int> vi; const int maxn = 4e7+7; int prime[maxn]; int vis[maxn]; int tot = 0; void getPrime(int n) { for (int i=2;i<=n;i++) { if (!vis[i]) prime[++tot] = i; for (int j=1;j<=tot;j++) { if (i*prime[j]>n) break; vis[i*prime[j]] = 1; if (i%prime[j]==0) break; } } } signed main() { getPrime(4e7); int t; cin>>t; while (t--) { int n; cin>>n; int cnt = 0; int l=1,r=1; int sum = 2; while (r<=tot&&prime[r]<=n) { while (sum>=n) { if (sum==n) cnt++; l++; sum -= prime[l-1]; } while (sum<n) { r++; sum += prime[r]; } } cout<<cnt<<'\n'; } }
E-X-factor Chains_牛客競賽數學專題班整數分解與篩法 (nowcoder.com)
對x分解質因數後,最大值就是每個質數因子的指數和,方案書用雜湊+記憶化搜尋+遞迴分治求出
#include <bits/stdc++.h> #define fi first #define se second #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef vector<int> vi; const int maxn = 1e6+7; const int LOG = 32; const ll base = 127; const ll p = 100029383; int a[LOG]; int vis[maxn]; int prime[maxn]; int tot = 0; int n; map<ll,ll> dp; ll getHash() { ll sum = 0; for (int i=1;i<=n;i++) { sum = (sum*base+a[i])%p; } return sum; } void getPrime(int n) { for (int i=2;i<=n;i++) { if (!vis[i]) prime[++tot] = i; for (int j=1;j<=tot;j++) { if (i*prime[j]>n) break; vis[i*prime[j]] = 1; if (i%prime[j]==0) break; } } } int getFac(int x) { int ind = 1; int j = 1; if (!vis[x]) { a[ind] = 1; return ind; } while (x>1) { if (!vis[x]) { a[ind]++; ind++; break; } while (x%prime[j]!=0) j++; while (x%prime[j]==0) { a[ind]++; x /= prime[j]; } ind++; } return ind-1; } ll func() { int cnt = 0; for (int i=1;i<=n;i++) { if (a[i]>0) cnt++; } if (cnt==1) return 1; ll h = getHash(); if (dp[h]) return dp[h]; ll res = 0; for (int i=1;i<=n;i++) { if (a[i]==0) continue; a[i]--; res += func(); a[i]++; } return dp[h] = res; } signed main() { IOS; int t; cin>>t; getPrime(maxn-1); while (t--) { memset(a,0,sizeof a); int x; cin>>x; n = getFac(x); int sum = 0; for (int i=1;i<=n;i++) { sum += a[i]; } sort(a+1,a+1+n); cout<<sum<<" "<<func()<<'\n'; } }
對A質因數分解,由正約數和公式,並且該公式的每個因子都是個等比數列和,可以直接算出結果,並且特判下乘法逆元不存在的情況
#include <bits/stdc++.h> #define fi first #define se second #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define L k<<1 #define R k<<1|1 using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef vector<int> vi; const int maxn = 5e7+7; const ll p = 9901; struct Node { int p,a; Node() { a = 0; } }; ll quick(ll x,ll n) { ll res = 1; while (n) { if (n&1) res = res * x % p; x = x * x % p; n >>= 1; } return res; } int prime[int(1e4+7)]; bool vis[int(1e4+7)]; int tot = 0; Node fac[100]; void getPrime(int n) { for (int i=2;i<=n;i++) { if (!vis[i]) prime[++tot] = i; for (int j=1;j<=n;j++) { if (i*prime[j]>n) break; vis[i*prime[j]] = 1; if (i%prime[j]==0) break; } } } int getFac(int x) { int ind = 1; int j = 1; while (x>1) { while (x%prime[j]!=0) { j++; if (prime[j]*prime[j]>x) { fac[ind].p = x; fac[ind].a = 1; ind++; return ind-1; } } while (x%prime[j]==0) { fac[ind].p = prime[j]; fac[ind].a++; x /= prime[j]; } ind++; } return ind-1; } int main() { int A,B; cin>>A>>B; if (A==0) { cout<<0; return 0; } getPrime(1e4); int n = getFac(A); ll res = 1; for (int i=1;i<=n;i++) { if ((fac[i].p-1)%p!=0) res = ((res*(quick(fac[i].p,fac[i].a*B+1)-1)%p*quick(fac[i].p-1,p-2))%p+p)%p; else res = res*(fac[i].a*B+1)%p; } cout<<res; }
易推出,由於n的範圍大,故要數論分塊,可得出答案
#include <bits/stdc++.h> #define fi first #define se second #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define L k<<1 #define R k<<1|1 using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef vector<int> vi; const int maxn = 5e7+7; int main() { int t; cin>>t; int cnt = 0; while (t--) { cnt++; ll n; cin>>n; ll r; ll res = 0; for (ll l=2;l<=n;l=r+1) { r = n/(n/l); res += (l+r)*(r-l+1)/2*(n/l-1); } // res -= (n+2)*(n-1)/2; cout<<"Case "<<cnt<<": "; cout<<res<<'\n'; } }