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 << '\n';
}
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 << '\n';
}
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\n";
else cout << "NO\n";
}
return 0;
}