Codeforces Round #665 (Div. 2)
阿新 • • 發佈:2020-08-22
目錄
Codeforces Round #665 (Div. 2)
A. Distance and Axis
題意: 給你一個點a的座標n,求點b的座標,使得∣OB−∣AB∣∣=K∣OB−∣AB∣∣=K
題解: 先判斷n和k的大小關係。b在OA中每移動一個點改變的大小為2,所以判斷n−kn−k的奇偶性即可
程式碼:
#include <bits/stdc++.h> using namespace std; int main() { int t; cin >> t; while (t--) { int n, k; cin >> n >> k; if (n > k) { if ((n - k) % 2 == 0) cout << 0 << endl; else cout << 1 << endl; } else cout << abs(n - k) << endl; } return 0; }
B. Ternary Sequence
題意: 有兩個由0,1,2組成的陣列,分別給你兩個陣列中0,1,2的個數,其中滿足
題解: 要讓2分的儘可能多,然後讓-2分的儘可能少,因此在取完2分的之後,讓0分的儘可能多,這樣2分的就儘可能少了
程式碼:
#include <bits/stdc++.h> using namespace std; typedef long long LL; int main() { int T; cin >> T; while (T--) { LL x1, y1, z1, x2, y2, z2; cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2; LL res = 0; LL t1 = min(z1, y2); z1 -= t1; y2 -= t1; res += t1 * 2; LL t2 = min(y1, x2); y1 -= t2, x2 -= t2; LL t3 = min(y1, y2); y1 -= t3, y2 -= t3; LL t4 = min(x1, x2); x1 -= t4, x2 -= t4; LL t5 = min(x1, y2); x1 -= t5, y2 -= t5; LL t6 = min(x1, z2); x1 -= t6, z2 -= t6; res -= 2 * min(y1, z2); cout << res << endl; } return 0; }
C. Mere Array
題意: 給你一個長度為n的陣列a,其中gcd(ai,aj)=min(a) 的兩兩元素可以做交換,求最後能否將陣列a改變成非遞減的陣列
題解: 把a陣列排序後,如果不在最後位置的元素那麼需要進行交換。由於任何兩個數字都可以通過和最小值進行交換,完成這兩個數字的交換。因此,如果不在最後位置的元素不是最小值的整數倍,那麼就無法完成交換。
程式碼:
#include <bits/stdc++.h> using namespace std; int const N = 1e5 + 10; typedef long long LL; LL a[N], n, T, b[N]; LL INF = 1e18; int main() { // int T; cin >> T; while (T--) { cin >> n; LL minv = INF; for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]), minv = min(minv, a[i]); memcpy(b, a, sizeof a); sort(b + 1, b + 1 + n); // vector<LL> v; int flg = 1; for (int i = 1; i <= n; ++i) { if (a[i] == b[i]) continue; if (a[i] % minv) { flg = 0; break; } } if (flg) cout << "YES\n"; else cout << "NO\n"; } return 0; }
D. Maximum Distributed Tree
題意: 給定一棵n 個結點的樹,對這棵樹分配邊權,使得這棵樹的邊權的乘積為k ,且要求所有兩點的簡單路徑邊權之和最大。k 以質因子的形式給出,有m 個質因子。結果取餘1e9+7
題解: dfs計算出每條邊被經過多少次,經過次數越多的分配的質數越大,即可得到最大值。要注意判斷指數情況和邊數不相等的情況。
程式碼:
#include <bits/stdc++.h>
using namespace std;
int const N = 1e5 + 10;
typedef long long LL;
LL a[N], n, e[N * 2], ne[N * 2], h[N], idx, m, zi[N], fazi[N], T;
LL INF = 1e18;
int mod = 1e9 + 7;
vector<LL> E;
void add(LL a, LL b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
LL dfs(int u, int fa)
{
LL sum = 1; // ans記錄子樹的最大值, sum記錄子樹點數和和u點
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (j == fa) continue;
LL son = dfs(j, u);
sum += son; // 更新sum
}
fazi[u] = max((LL)0, n - sum);
zi[u] = sum;
return sum;
}
int main() {
cin >> T;
while (T--) {
cin >> n;
memset(fazi, 0, sizeof fazi);
E.clear();
memset(zi, 0, sizeof zi);
memset(h, -1, sizeof h);
idx = 0;
for (int i = 1; i <= n - 1; ++i) {
LL a, b;
scanf("%lld %lld", &a, &b);
add(a, b), add(b, a);
}
dfs(1, -1);
cin >> m;
vector<LL> v;
for (int i = 1; i <= m; ++i) {
LL k;
scanf("%lld", &k);
v.push_back(k);
}
sort(v.begin(), v.end());
reverse(v.begin(), v.end());
for (int i = 2; i <= n; ++i) {
E.push_back(zi[i] * fazi[i]);
}
sort(E.begin(), E.end());
reverse(E.begin(), E.end());
// cout << E.size() << endl;
if (v.size() < E.size()) {
while (v.size() < E.size()) v.push_back(1);
}
else if (v.size() > E.size()) {
vector<LL> v3(v.begin(), v.begin() + v.size() - E.size() + 1);
vector<LL> v2(v.begin() + v.size() - E.size() + 1, v.end());
LL mul = 1;
for (auto v3i: v3) mul = (mul * v3i ) % mod;
v2.push_back(mul);
sort(v2.begin(), v2.end());
reverse(v2.begin(), v2.end());
v = v2;
}
LL res = 0;
for (int i = 0; i < E.size(); ++i) {
res = (res + E[i] * v[i] % mod) % mod;
}
cout << res << endl;
}
return 0;
}