Codeforces Round #641 (Div. 2)

A

每次加一个最小因子(大于1), 但是由于k>1,

1当f(n) = n (n为质数), --k, n += f(n), 使得f(n') = 2

2 f(n) = a, n = a * c (a <= c) a为偶数2

3 f(n) = a, n = a * c (a <= c) a为任意奇数(c也为任意奇数, 否则c可以拆为 2 * c', 则f(n) = a = 2), 则 --k, n' = a * (c + 1), c变偶数了, 则f(n') = a' = 2

所以无论如何可以消耗一次k,使得f(n) = 2, 那剩下的无非就是 2 * (n / 2 + k)

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef double db;
 
const int maxn = 1e5;
 
int n, m, _;
 
int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    for (cin >> _; _; --_)
    {
        ll n, k, a = 2, c; cin >> n >> k;
        while (n % a) ++a; c = n / a;
        if (c == 1) --k, c = a, a = 2;
        if (a != 2) --k, c = a * (c + 1) / 2, a = 2;
        cout << (c + k) * a << '
';
    }
    return 0;
}

B

dp(不太好想), 好想的话, 还是写记忆化搜索

直接看代码吧, 就是普通记忆化搜索

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef double db;
 
const int maxn = 1e5 + 5;
 
int n, m, _;
int f[maxn], a[maxn];
 
int dp(int u)
{
    if (f[u]) return f[u];
 
    for (int i = 2; i * u <= n; ++i)
        if (a[i * u] > a[u])
            f[u] = max(f[u], dp(i * u));
    return ++f[u];
}
 
 
int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    for (cin >> _; _; --_)
    {
        cin >> n; int ans = 0;
        rep (i, 1, n) cin >> a[i], f[i] = 0;
        rep (i, 1, n) ans = max(ans, dp(i));
        cout << ans << '
';
    }
    return 0;
}

C

自己写写画画, 会发现对于答案的每个因子

必定是 a[1] ~ a[n] 中 n或(n-1)个数的因子, 否则答案不可能含有这个因子

所以简单了

先枚举a[1]的所有因子, 看看其他数时候含有这个因子(最多一个数没有), 则这个因子必定出现在答案中, 其他数将这个因子除去

然后再枚举a[2]的所有因子, 这次其他的(a[1]除外)数必须都有这个因子(a[1]没有, 如果a[1]有, 再第一次循环就已经除掉了), 操作同上

再加点细节优化, 就水过了

记得特判

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef double db;
 
const int maxn = 1e5 + 5;
 
int n, m, _, ans = 1, res = 1;
int a[maxn];
 
bool work(int k, int d, int z)
{
    int flag = 0;
    rep (j, k + 1, n)
    {
        if (res != 1 && a[j] % res == 0) a[j] /= res;
        if (flag > z) continue;
        if (a[j] % d && flag <= z) ++flag;
        if (flag > z && res == 1) break;
    }
 
    res = 1; 
    if (flag <= z) ans *= d, res = d; 
    return (res != 1);
}
 
int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n; 
    rep (i, 1, n) cin >> a[i];
    sort(a + 1, a + 1 + n);
        
    if (n == 2) { cout << ((ll)a[1] * a[2] / __gcd(a[1], a[2])); return 0; }
 
    for (int i = 2; i <= a[1]; ++i)
    {
        if (a[1] % i) continue;
        if (work(1, i, 1)) a[1] /= i, --i;
    }
 
    for (int i = 2; i <= a[2]; ++i)
    {
        if (a[2] % i) continue;
        if (work(2, i, 0)) a[2] /= i, --i;
    }
 
    cout << ans;
    return 0;
}

D

小细节特判直接看代码,主要说思路

1.对于两个相邻的数 a[x] <= a[y], 则可以将 a[y] 变为 a[x], 然后整个序列就会都可以改成a[x]

2.对于三个相邻的数 a[j] >= k && a[j + 2] >= k 则 a[j],a[j + 1], a[j + 2]都可以变为一个 >= k的数, 然后覆盖整个序列

所以问题变成了, 是否可以将 a[i] == k 两边的 a[i - 1] 和 a[i + 1] 变为 >= k

找存在 a[i] >= k 且 a[i + 2] >= k , 或者 a[i] >= k 且 a[i + 1] >= k 就 "YES"

记得特判特殊情况就行

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef double db;

const int maxn = 1e5 + 5;

int n, m, _;
int a[maxn];

int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    for (cin >> _; _; --_)
    {
        cin >> n >> m;
        int flag = 0, f = 0; 

        rep (i, 1, n)
        {
            cin >> a[i];
            if (a[i] == m) ++f;
            if (flag) continue;
            if (i > 1 && a[i] >= m && a[i - 1] >= m) flag = 1;
            if (i > 2 && a[i] >= m && a[i - 2] >= m) flag = 1;
        }

        if (n == 1 && a[1] == m) flag = 1;
        
        if (flag && f) cout << "YES
";
        else cout << "NO
";
    }
    return 0;
}
原文地址:https://www.cnblogs.com/2aptx4869/p/12885307.html