QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#263614 | #5421. Factories Once More | KhNURE_KIVI | TL | 384ms | 211028kb | C++20 | 10.1kb | 2023-11-24 23:35:37 | 2023-11-24 23:35:39 |
Judging History
answer
//#pragma GCC optimize("Ofast", "unroll-loops")
//#pragma GCC target("sse", "sse2", "sse3", "ssse3", "sse4")
#ifdef LOCAL
#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstdint>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <random>
#include <deque>
#include <functional>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <complex>
#include <numeric>
#include <cassert>
#include <array>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <thread>
#else
#include <bits/stdc++.h>
#endif
#define all(a) a.begin(),a.end()
#define len(a) (int)(a.size())
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
template<typename T>
inline bool umin(T &a, T b) {
if (b < a) {
a = b;
return true;
}
return false;
}
template<typename T>
inline bool umax(T &a, T b) {
if (a < b) {
a = b;
return true;
}
return false;
}
#ifdef LOCAL
#define D for (bool _FLAG = true; _FLAG; _FLAG = false)
#define LOG(...) print(#__VA_ARGS__" ::", __VA_ARGS__) << endl
template <class ...Ts> auto &print(Ts ...ts) { return ((cerr << ts << " "), ...); }
#else
#define D while (false)
#define LOG(...)
#endif // LOCAL
const int max_n = 1e5 + 11, inf = 1000111222;
//struct point {
// int x, y;
//};
//
//inline bool cmp (point a, point b) {
// return a.x < b.x || a.x == b.x && a.y < b.y;
//}
//
//inline bool cw (point a, point b, point c) {
// return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) < 0;
//}
//
//inline bool ccw (point a, point b, point c) {
// return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) > 0;
//}
//
//void convex_hull (vector<point> & a) {
// if (len(a) <= 1) {
// return;
// }
// sort (a.begin(), a.end(), cmp);
// point p1 = a[0], p2 = a.back();
// vector<point> up = {p1}, down = {p1};
// for (int i = 1; i < len(a); i++) {
// if (i == len(a) - 1 || cw (p1, a[i], p2)) {
// while (len(up) >= 2 && !cw(up[len(up) - 2], up.back(), a[i])) {
// up.pop_back();
// }
// up.pb(a[i]);
// }
// if (i == len(a) - 1 || ccw (p1, a[i], p2)) {
// while (len(down) >= 2 && !ccw(down[len(down) - 2], down.back(), a[i])) {
// down.pop_back();
// }
// down.pb(a[i]);
// }
// }
// a = up;
//// for (int i = len(down) - 2; i > 0; i--) {
//// a.pb(down[i]);
//// }
//}
//
//
//
//int dp[max_n][max_n], n, k, cnt[max_n];
//
//ll area(const vector<point>& fig) {
// ll res = 0;
// for (unsigned i = 0; i < fig.size(); i++) {
// point p = i ? fig[i - 1] : fig.back();
// point q = fig[i];
// res += (p.x - q.x) * (p.y + q.y);
// }
// return abs(res);
//}
//inline void dfs (int v, int p = -1) {
// cnt[v] = 1;
// for (auto [to, len] : edge[v]) {
// if (to == p) {
// continue;
// }
// dfs(to, v);
// for (int i1 = k; i1 >= 0; i1--) {
// for (int j = min(cnt[to], k - i1); j >= 0; j--) {
// umax(dp[v][i1 + j], dp[to][j] + dp[v][i1] + len * j * (k - j));
// if (i1 + j + 1 <= k) {
// umax(dp[v][i1 + j + 1], dp[to][j] + dp[v][i1] + len * j * (k - j));
// }
// }
// }
// cnt[v] += cnt[to];
// }
// vector <point> have;
//// LOG(cnt[v]);
// for (int i = 0; i <= min(k, cnt[v]); i++) {
// have.pb(point{i, dp[v][i]});
//// LOG(i, dp[v][i]);
// }
// auto h = have;
// convex_hull(h);
//// LOG(len(have), len(h), area(have), area(h));
//// assert(area(have) == area(h));
// if (area(have) != area(h)) {
// exit(3);
// }
//}
struct dsu {
public:
int n;
vector <int> p, cnt;
inline void make_set (int v) {
p[v] = v;
}
dsu (int n) : n(n) {
p.resize(n);
cnt.assign(n, 1);
for (int i = 0; i < n; i++) {
make_set(i);
}
}
inline int get (int v) {
if (p[v] == v) return v;
return p[v] = get(p[v]); /// compressing path
}
inline bool unite (int a, int b) {
a = get(a);
b = get(b);
if (a == b) return false;
if (cnt[a] > cnt[b]) {
swap(a, b);
}
p[a] = b;
cnt[b] += cnt[a];
return true;
}
};
const int debug = 0;
vector <pii> edge[max_n];
mt19937 rng(228);
template<typename T = int>
inline T randll(T l = INT_MIN, T r = INT_MAX) {
return uniform_int_distribution<T>(l, r)(rng);
}
inline ld randld(ld l = INT_MIN, ld r = INT_MAX) {
return uniform_real_distribution<ld>(l, r)(rng);
}
vector <int> used;
inline int dfs (int v, int ¢er, int sz, int p = -1) {
int cnt = 1;
for (auto &i : edge[v]) {
if (i.first != p && !used[i.first]) {
cnt += dfs(i.first, center, sz, v);
}
}
if (center == -1 && cnt + cnt > sz)
center = v;
return cnt;
}
struct point {
ll x, y;
point operator + (const point & p) const {
return point{x + p.x, y + p.y};
}
point operator - (const point & p) const {
return point{x - p.x, y - p.y};
}
ll cross(const point & p) const {
return x * p.y - y * p.x;
}
};
void reorder_polygon(vector<point> & P){
size_t pos = 0;
for(size_t i = 1; i < P.size(); i++){
if(P[i].y < P[pos].y || (P[i].y == P[pos].y && P[i].x < P[pos].x))
pos = i;
}
rotate(P.begin(), P.begin() + pos, P.end());
}
vector<point> minkowski(vector<point> P, vector<point> Q){
// the first vertex must be the lowest
reorder_polygon(P);
reorder_polygon(Q);
// we must ensure cyclic indexing
P.push_back(P[0]);
P.push_back(P[1]);
Q.push_back(Q[0]);
Q.push_back(Q[1]);
// main part
vector<point> result;
size_t i = 0, j = 0;
while(i < P.size() - 2 || j < Q.size() - 2){
// LOG(i, j);
result.push_back(P[i] + Q[j]);
auto cross = (P[i + 1] - P[i]).cross(Q[j + 1] - Q[j]);
if(cross >= 0 && i < P.size() - 2)
++i;
if(cross <= 0 && j < Q.size() - 2)
++j;
}
return result;
}
vector <ll> dp[max_n];
int n, k;
vector <int> GG;
inline void convolve (int a, int b) {
vector <point> A(len(dp[a])), B(len(dp[b]));
for (int i = 0; i < len(dp[a]); i++) {
A[i] = point{ dp[a][i], i};
}
for (int i = 0; i < len(dp[b]); i++) {
B[i] = point{dp[b][i], i};
}
auto res = minkowski(A, B);
dp[a].resize(min(k + 1, len(A) + len(B) - 1));
int j = 1;
ll last = 0, val = 0;
if (res[0].y != 0 || res[0].x != 0) {
exit(47);
}
// LOG("here");
// for (auto &i : res) {
// LOG(i.x, i.y);
// }
for (int i = 1; i < len(res); i++) {
// LOG(i);
// LOG(res[i].y);
while (j < res[i].y && j < len(dp[a])) {
dp[a][j] = (j - last) * (res[i].x - val) + val * (res[i].y - last);
if (dp[a][j] % (res[i].y - last) != 0) {
exit(48);
}
dp[a][j] /= (res[i].y - last);
// LOG(j, dp[a][j]);
++j;
}
if (j < len(dp[a])) {
if (j != res[i].y) {
exit(49);
}
dp[a][j] = res[i].x;
++j;
}
if (last > res[i].y) {
break;
}
last = res[i].y;
val = res[i].x;
}
LOG(len(res));
dp[b].clear();
// LOG(j, len(dp[a]));
if (j != len(dp[a])) {
exit(50);
}
// for (auto &kk : dp[a]) {
// LOG(kk);
// }
}
inline int calc (int l, int r) {
if (l == r) {
return GG[r];
}
int x = (l + r) >> 1;
int L = calc(l, x);
int R = calc(x + 1, r);
convolve(R, L);
return R;
}
int cnt[max_n];
inline void dfs (int v, int p = -1) {
cnt[v] = 1;
vector <int> gg;
for (auto [to, len] : edge[v]) {
if (to == p) {
continue;
}
dfs(to, v);
for (int j = 0; j < len(dp[to]); j++) {
dp[to][j] += len * 1ll * j * (k - j);
}
gg.pb(to);
cnt[v] += cnt[to];
}
if (gg.empty()) {
dp[v].resize(2);
}
else {
GG = gg;
int where = calc(0, len(GG) - 1);
dp[where].swap(dp[v]);
int need = min({cnt[v], k});
dp[v].resize(need + 1);
for (int j = len(dp[v]) - 1; j > 0; j--) {
umax(dp[v][j], dp[v][j - 1]);
}
}
}
int main() {
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
m1:
n = 1e5;
for (int i = 0; i <= n; i++) {
edge[i].clear();
// for (int j = 0; j <= n; j++) {
// dp[i][j] = 0;
// }
}
k = n;
if (!debug) {
cin >> n >> k;
}
used.resize(n);
dsu t(n);
LOG("here");
for (int i = 1, u, v, w; i < n; i++) {
if (!debug) {
cin >> u >> v >> w;
--u, --v;
}
else {
u = i, v = i - 1;
w = randll(1, 100);
// u = randll(0, n - 1);
// v = randll(0, n - 1);
while (!t.unite(u, v)) {
u = randll(0, n - 1);
v = randll(0, n - 1);
}
}
edge[u].pb({v, w});
edge[v].pb({u, w});
}
dfs(0);
cout << dp[0][k] << '\n';
LOG(n, k);
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 8244kb
input:
6 3 1 2 3 2 3 2 2 4 1 1 5 2 5 6 3
output:
22
result:
ok 1 number(s): "22"
Test #2:
score: 0
Accepted
time: 2ms
memory: 8240kb
input:
4 3 1 2 2 1 3 3 1 4 4
output:
18
result:
ok 1 number(s): "18"
Test #3:
score: 0
Accepted
time: 2ms
memory: 8328kb
input:
2 2 1 2 1
output:
1
result:
ok 1 number(s): "1"
Test #4:
score: 0
Accepted
time: 47ms
memory: 18304kb
input:
100000 17 37253 35652 9892 56367 53643 1120 47896 49255 4547 93065 88999 1745 5251 6742 5031 49828 50972 8974 31548 46729 1032 56341 56287 4812 21896 22838 1682 82124 90557 7307 76289 76949 7028 33834 45380 6856 15499 15064 2265 10127 5251 9920 87208 93945 9487 68990 72637 6891 91640 85004 2259 4748...
output:
4915539756
result:
ok 1 number(s): "4915539756"
Test #5:
score: 0
Accepted
time: 62ms
memory: 21952kb
input:
100000 54 52645 54121 2692 53845 52739 658 88841 87795 9298 79147 80362 6720 80683 80909 7138 30882 28439 3197 85375 85227 6903 80229 77345 445 79601 78148 7956 15262 16666 8402 87894 95824 844 17024 12005 5687 63972 65707 8592 40510 45074 9135 50774 49596 7692 37825 38581 9735 18425 8926 1747 84473...
output:
42231195087
result:
ok 1 number(s): "42231195087"
Test #6:
score: 0
Accepted
time: 74ms
memory: 24392kb
input:
100000 102 16851 15608 9173 34201 33232 4258 54234 53975 3926 85209 83376 6251 7847 6527 2379 92238 90747 5818 74729 75538 1672 98398 98838 6273 53445 54006 4317 32889 33232 9974 12450 15916 1801 40600 40892 1397 81713 79934 4580 28979 30696 8260 90747 94477 5725 54584 53210 3583 53396 53535 1868 88...
output:
175914470238
result:
ok 1 number(s): "175914470238"
Test #7:
score: 0
Accepted
time: 81ms
memory: 29280kb
input:
100000 497 25231 28005 505 36245 34348 7087 59602 57941 1691 77459 74493 7828 11601 4890 9847 11168 11760 3807 97468 93452 8094 14843 13669 488 97738 96869 5615 27369 25231 3081 79596 78931 4604 47155 45416 1728 49273 49193 7851 38358 38735 4842 18025 23117 6165 32677 32970 9931 34174 35023 9709 688...
output:
4545765711714
result:
ok 1 number(s): "4545765711714"
Test #8:
score: 0
Accepted
time: 121ms
memory: 52860kb
input:
100000 1008 9180 10823 9475 54255 56689 9732 42103 43318 4094 11647 12305 5651 63247 66770 513 88023 85592 3518 65473 66850 7176 3995 6958 9978 2408 780 982 71617 71736 9828 22243 19070 9488 41041 40935 2604 2697 6337 8631 90433 86018 7306 73087 76067 9705 92594 99998 6304 70188 68983 8730 13139 132...
output:
11601533653407
result:
ok 1 number(s): "11601533653407"
Test #9:
score: 0
Accepted
time: 384ms
memory: 209744kb
input:
100000 4998 4535 1424 2772 79531 75798 6655 29016 24101 7995 82506 82511 2829 62622 55576 6770 13299 12683 7014 10087 7482 4906 54613 61198 7397 38305 37235 7840 78676 78348 906 68742 70584 5410 96124 96972 9461 84908 86633 3419 99187 98820 1644 34611 31584 1458 18895 19637 6568 38305 39973 5203 324...
output:
464391127886092
result:
ok 1 number(s): "464391127886092"
Test #10:
score: 0
Accepted
time: 381ms
memory: 211028kb
input:
100000 9995 65827 63216 3734 63002 63137 8069 19664 18828 9617 93059 93073 5416 98904 95848 3168 32077 28643 9290 85544 83781 4681 79065 75963 8553 52322 55020 5603 19063 21141 9921 17961 14354 9378 46073 48153 7631 44812 43844 24 72171 73621 177 28060 35086 186 96739 99367 1792 39346 41459 6809 254...
output:
1257975734249836
result:
ok 1 number(s): "1257975734249836"
Test #11:
score: -100
Time Limit Exceeded
input:
100000 20006 61719 62750 1537 44716 44507 9463 9473 13052 6509 88729 91128 7872 17510 17537 3948 31118 28068 695 84397 87761 9471 46545 52049 9288 40481 42157 9669 77649 82807 4870 25263 34334 9049 87761 87116 9621 21481 22885 9068 12531 13961 118 4102 1090 7301 73658 74721 1190 93332 93176 6754 139...