contest 1350
A. Orac and Factors
定义一个操作为找出一个数除1外的最小因数,并用这个因数加上该数。给定初始数和操作次数,要求计算操作后的结果。
显然如果一个数是偶数的话,这个因数是2,并且操作后的因数依旧是2。而如果这个数是奇数,则其因数也是奇数,操作后变成偶数。
因此给定初始数x和操作数k的话 结果为x+f(x)+2*(k-1)
以下代码
#include <iostream> #include<queue> #include<map> #include<utility> #include<vector> #include<algorithm> #include<cstring> #include<string> #include<stdio.h> #include<sstream> #include<fstream> #include<cmath> #include<set> #include<math.h> using namespace std; typedef long long ll; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! typedef pair<int, int> P; int m, n, t,f,w,x; int dat[10000+105] = {}; int cnt[26] = {}; vector<int> s; void solve() { cin >> m >> n; ll ans = m; int isprime = 1; int fact = m; for (int i = 2; i<int(sqrt(m * 1.0)) + 1; i++) { if (m % i == 0) { fact = i; isprime = 0; break; } } ans += fact; for (int i = 0; i < n - 1; i++) ans += 2; cout << ans << endl; } int main() { cin >> t; for(int i = 0; i < t; ++i) { solve(); } return 0; }
B. Orac and Models
给定一个数列,下标从1开始,求最长的升序子序列长度,且该子序列中,后一项的小下标可以被前一项整除
我们可以用 dp解决问题
#include <iostream> #include<queue> #include<map> #include<utility> #include<vector> #include<algorithm> #include<cstring> #include<string> #include<stdio.h> #include<sstream> #include<fstream> #include<cmath> #include<set> #include<math.h> using namespace std; typedef long long ll; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! typedef pair<int, int> P; int m, n, t,f,w,x; int dat[100000 +105] = {}; int cnt[100000+105] = {}; vector<int> s; int max(int a, int b) { if (a > b)return a; return b; } void solve() { cin >> m; for (int i = 0; i < m; i++) { cin >> cnt[i+1]; dat[i+1] = 1; } for (int i = 1; i <=m; i++) { for (int j = i; j+i <= m; j += i) { if (cnt[i] < cnt[j + i]) dat[j + i] = max(dat[j + i], dat[i] + 1); } } int ans = 0; for (int i = 0; i < m; i++) ans = max(ans, dat[i + 1]); cout << ans << endl; } int main() { cin >> t; for(int i = 0; i < t; ++i) { solve(); } return 0; }
C. Orac and LCM
给定一个序列 要你求 gcd({lcm({ai,aj}) | i<j})
有以下结论
gcd(lcm(a,b),lcm(a,c)) = gcd(ab/gcd(a,b), ac/gcd(a,c)) = a*gcd(b,c)/gcd(a, b, c)=lcm(a, gcd(b,c))
所以我们先预处理后缀gcd,然后对于每个数我们求其与其后缀gcd的lcm
最后在求一次gcd
#include <iostream> #include<queue> #include<map> #include<utility> #include<vector> #include<algorithm> #include<cstring> #include<string> #include<stdio.h> #include<sstream> #include<fstream> #include<cmath> #include<set> #include<math.h> using namespace std; typedef long long ll; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! typedef pair<int, int> P; ll a, b; vector<int> t1,t; string in; bool vis[105]; ll p2[10000000] = {}; ll p[10000000] = {}; ll gcd(ll a, ll b) { if (b == 0) return a; else return gcd(b, a % b); } int main() { int n; cin >> n; for (int i = 0; i < n; i++) { cin >> p[i]; } int temp = 0; for (int i = n - 1; i >= 0; i--) { temp = gcd(temp, p[i]); p2[i] = temp; } ll ans; for (int i = 0; i < n - 1; i++) { if (i == 0) ans = p[0] * p[1] / gcd(p[0], p2[1]); else ans = gcd(ans, p[i] * p2[i + 1] / gcd(p[i], p2[i + 1])); } cout << ans; return 0; }