Codeforces Round #641 Div. 2

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;
}

猜你喜欢

转载自www.cnblogs.com/pophirasawa/p/12942010.html