题目 链接
A.青蛙的约会
我们把这两只青蛙分别叫做青蛙\(A\)和青蛙\(B\),并且规定纬度线上东经\(0\)度处为原点,由东往西为正方向,单位长度\(1\)米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是\(x\),青蛙\(B\)的出发点坐标是\(y\)。青蛙\(A\)一次能跳\(m\)米,青蛙\(B\)一次能跳\(n\)米,两只青蛙跳一次所花费的时间相同。纬度线总长$ L$米。现在要你求出它们跳了几次以后才会碰面。
变形得到:\({(m-n)* t + l * k = y-x }\) ,\((k\in Z)\)
题目等价于求最小正整数解 \(t\)。套板子即可
#include <bits/stdc++.h using namespace std; typedef long long int ll; #define dbg(x...) do { cout << #x << " -> "; err(x); } while(0) #define endl '\n' #define tententen ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr); const ll N = 1e5 + 10; const ll INF = 0x3f3f3f3f3f3f3f3f; const int inf = 0x3f3f3f3f; void err() { cout << endl;} template
void err(const T &arg, const Ts &... args) {cout << arg << ' ';err(args...);} ll ex_gcd(ll a, ll b, ll &x, ll &y) { if (!b) { x = 1, y = 0; return a; } ll ans = ex_gcd(b, a % b, x, y); ll t = x; x = y; y = t - a / b * y; return ans; } void solve() { ll xx, yy, n, m, l, x, y; cin >> xx >> yy >> m >> n >> l; ll dis = n - m, c = xx - yy; if (dis < 0) { dis *= -1; c *= -1; } ll g = ex_gcd(dis, l, x, y); if (c % g) { puts("Impossible"); return; } x *= (c / g); cout << (x % (l / g) + l / g) % (l / g) << endl; } int main() { tententen int T = 1; // cin>>T; while (T--) { solve(); } return 0; }
B.Sum of Consecutive Prime Numbers
一些正整数可以用一个或多个连续素数的和来表示。给出一个正整数 $ n$,有多少种不同的表示形式?
#include <bits/stdc++.h> using namespace std; typedef long long int ll; #define dbg(x...) do { cout << #x << " -> "; err(x); } while(0) #define endl '\n' #define tententen ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr); const int N = 4e7 + 5; const ll INF = 0x3f3f3f3f3f3f3f3f; const int inf = 0x3f3f3f3f; void err() { cout << endl;} template
void err(const T &arg, const Ts &... args) {cout << arg << ' ';err(args...);} int prime[N],tot=0; bool not_prime[N]; int ans[N],res[N]; struct node{ int num,id; bool operator < (const node &t)const{ return num < t.num ; } }a[N]; void divide(int N) { for (int i = 2; i <= N; ++i) { if (!not_prime[i]) { prime[++tot] = i; } for (int j = 1; j <= tot && i * prime[j] <= N; ++j) { not_prime[i * prime[j]] = 1; if (i % prime[j] == 0) { break; } } } } void solve() { int t; cin >> t; for (int i = 1; i <= t; ++i) { cin >> a[i].num; a[i].id = i; } sort(a + 1, a + 1 + t); int cnt = 0; for (int i = 1; i <= t; ++i) { cnt = 0; if (ans[a[i].num] != -1) { res[a[i].id] = ans[a[i].num]; continue; } int l = 1, r = 1; int sum = prime[1]; while (r <= tot && l <= r) { while (r <= tot && sum < a[i].num) { r++; sum += prime[r]; } if (sum == a[i].num) { cnt++; sum -= prime[l]; l++; } else { sum -= prime[l]; l++; } } ans[a[i].num] = cnt; res[a[i].id] = cnt; } for (int i = 1; i <= t; ++i) { cout << res[i] << endl; } } int main() { tententen; int T = 1; // cin>>T; divide(N - 4); memset(ans, -1, sizeof(ans)); while (T--) { solve(); } return 0; }
C.Prime Distance
你要找到区间中最接近的两个相邻素数\(C1\) 和\(C2\) \((L\leq C1 \le C2≤R)\)(即$ C2-C1$是最小值),
如果还有其他相距相同的对,请输出第一对。
你要找到区间中最接近的两个相邻素数\(D1\) 和\(D2\) \((L\leq D1 \le D2≤R)\)(即$ D2-D1$是最大值)尽可能远离。如果有距离相同的,再次选择第一对。
即必然存在两个因子\(d\)和\(n/d\),假设\(d \leq n/d\),则\(d \leq n/d\),即\(n\)必然存在一个小于\(sqrt(n)\)的因子
所以先预处理出 \(sqrt(N)\)范围内的全部素数,那么就可以通过这些素数继续来筛选\(sqrt(N)-N\)内的的质数,然后对于每一个区间暴力即可
#include <bits/stdc++.h> using namespace std; typedef long long int ll; #define dbg(x...) do { cout << #x << " -> "; err(x); } while(0) #define endl '\n' #define tententen ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr); const ll N = 1e5 + 10; const ll INF = 0x3f3f3f3f3f3f3f3f; const int inf = 0x3f3f3f3f; void err() { cout << endl;} template
void err(const T &arg, const Ts &... args) {cout << arg << ' ';err(args...);} int prime[N*10],tot=0; bool not_prime[N*10]; int vis[N*20]; void divide(int N) { for (int i = 2; i <= N; ++i) { if (!not_prime[i]) { prime[++tot] = i; } for (int j = 1; j <= tot && i * prime[j] <= N; ++j) { not_prime[i * prime[j]] = 1; if (i % prime[j] == 0) { break; } } } } void solve() { int l, r; cin >> l >> r; l=max( l, 2ll ); int pre = 0, mn = inf, mx = 0, l1, l2, r1, r2, cnt = 0; if (r <= 1e5) { for (int i = l; i <= r; ++i) { if (!not_prime[i]) { cnt++; if (cnt == 1) { pre = i; continue; } if (i - pre < mn) { l1 = pre, r1 = i; mn = min(i - pre, mn); } if (i - pre > mx) { l2 = pre, r2 = i; mx = max(i - pre, mx); } pre = i; } } } else { for (int i = 1; i <= r - l + 1; ++i) { vis[i] = 0; } for (int i = 1; i <= tot && prime[i] <= r; ++i) { int pre = max((l - 1) / prime[i] + 1, 2ll), lst = r / prime[i]; for (int j = pre; j <= lst; ++j) { vis[(ll) j * prime[i] - l + 1] = 1; } } for (int i = 1; i <= r - l + 1; ++i) { if (!vis[i]) { cnt++; if (cnt == 1) { pre = i; continue; } if (i - pre < mn) { l1 = pre + l - 1, r1 = i + l - 1; mn = min(i - pre, mn); } if (i - pre > mx) { l2 = pre + l - 1, r2 = i + l - 1; mx = max(i - pre, mx); } if(i+l!=2)pre = i; } } } if (cnt < 2) { cout << "There are no adjacent primes." << endl; } else { cout << l1 << "," << r1 << " are closest, " << l2 << "," << r2 << " are most distant." << endl; } } signed main() { tententen; int T = 1; cin >> T; divide((N - 1)); while (T--) { solve(); } return 0; }
D1.Zero-One (Easy Version)
但输入并不是一个正整数 \(n\),而是给出 \(k\)组 \(pi,ei\),\(n=p1^{e1}∗p2^{e2}∗...∗pk^{ek}\),其中 \(pi\)为素数,且 $ pi > pi+1$ ,\({e_i>0}\)
输出时也需要按上述格式输出。
#include <bits/stdc++.h> using namespace std; typedef long long int ll; #define dbg(x...) do { cout << #x << " -> "; err(x); } while(0) #define endl '\n' #define tententen ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr); const ll N = 1e5 + 10; const ll INF = 0x3f3f3f3f3f3f3f3f; const int inf = 0x3f3f3f3f; void err() { cout << endl;} template
void err(const T &arg, const Ts &... args) {cout << arg << ' ';err(args...);} ll ksm(ll a, ll b) {ll ans = 1;while (b > 0) {if (b & 1) {ans = ans * a ;}a = a * a ;b >>= 1;}return ans;} int prime[N],tot=0; bool not_prime[N]; void divide(int N) { for (int i = 2; i <= N; ++i) { if (!not_prime[i]) { prime[++tot] = i; } for (int j = 1; j <= tot && i * prime[j] <= N; ++j) { not_prime[i * prime[j]] = 1; if (i % prime[j] == 0) { break; } } } } string s; int n,num; void solve() { vector ans; num = 1; cin>>n; for (int i = 1, x, y; i <= n; ++i) { cin >> x >> y; num *= ksm(x, y); } num--; for (int i = tot; i >= 1; --i) { if (num % prime[i] == 0) { ans.push_back(prime[i]); int cnt = 0; while (num % prime[i] == 0) { cnt++, num /= prime[i]; } ans.push_back(cnt); } } for (int i = 0; i < ans.size(); ++i) { cout << ans[i] << " \n"[i == ans.size() - 1]; } } signed main() { tententen; int T = 1; cin >> T; divide((N - 1)); while (T--) { solve(); } return 0; }
E. Conveyor
其中 \(a_0=1,a_m=x,a_i<a_i+1\) ,\(a_i|a_{i+1}\)
求能构造出的序列中 \(m\)的最大值,以及 \(m\)等于最大值时的方案数
\(n\)个不同的数的全排列除去重复的就是\(n!\)除以每个重复因子数的阶乘
标签:err,专题,const,cout,筛法,int,ll,牛客,define From: https://www.cnblogs.com/tentenn/p/16874941.html#include <bits/stdc++.h> using namespace std; typedef long long int ll; #define dbg(x...) do { cout << #x << " -> "; err(x); } while(0) #define endl '\n' #define int ll #define tententen ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr); const ll N = 1e3 + 10; const ll INF = 0x3f3f3f3f3f3f3f3f; const int inf = 0x3f3f3f3f; void err() { cout << endl;} template
void err(const T &arg, const Ts &... args) {cout << arg << ' ';err(args...);} ll ksm(ll a, ll b) {ll ans = 1;while (b > 0) {if (b & 1) {ans = ans * a ;}a = a * a ;b >>= 1;}return ans;} ll fac[N]; void init(){ fac[1]=1; for(int i=2;i<=N;++i){ fac[i]=fac[i-1]*i; } } void solve() { int num,cnt,tmp=0,res=1; cin>>num; for(int i=2;i*i<=num;++i){ if(!(num%i)){ cnt=0; while(!(num%i)){ num/=i; ++cnt; } tmp+=cnt; res*=fac[cnt]; } } if(num>1){ ++tmp; } int ans=fac[tmp]/res; cout<<tmp<<" "<<ans<<endl;="" }="" signed="" main()="" {="" tententen;="" int="" t="1;" cin="">> T; init(); while (T--) { solve(); } return 0; }