Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define int long long
- vector<long long> C[100005];
- long long Val[100005];
- map<long long, int> taken;
- int n;
- int nodes = 0;
- pair<int, int> T[7000005];
- int Left[7000005], Right[7000005];
- bool cmp(pair<int, int> a, pair<int, int> b) {
- return C[a.first][a.second] < C[b.first][b.second];
- }
- int inc(int x, int b, int e, int pos, int val) {
- int ret = ++nodes;
- Left[ret] = Left[x];
- Right[ret] = Right[x];
- if(b == e) {
- if(val == -1)
- return 0;
- T[ret] = {pos, val};
- } else {
- int m = (b + e) / 2;
- if(pos <= m) Left[ret] = inc(Left[ret], b, m, pos, val);
- else Right[ret] = inc(Right[ret], m + 1, e, pos, val);
- T[ret] = min(T[Left[ret]], T[Right[ret]], cmp);
- }
- return ret;
- }
- struct qnode {
- long long has, cost;
- int root;
- long long getcost() const {
- return cost + C[T[root].first][T[root].second];
- }
- long long gethash() const {
- return has + Val[T[root].first];
- }
- bool operator<(const qnode &oth) const {
- return getcost() > oth.getcost();
- }
- };
- int32_t main() {
- //srand(time(0));
- int k;
- freopen("roboherd.in", "r", stdin);
- freopen("roboherd.out", "w", stdout);
- cin >> n >> k;
- T[0] = {n + 1, 0};
- C[n + 1].push_back(1e18);
- for(int i = 0; i < n; ++i) {
- int cnt;
- cin >> cnt;
- C[i].resize(cnt);
- Val[i] = 1LL * rand() * rand();
- for(auto &x : C[i])
- cin >> x;
- sort(C[i].begin(), C[i].end());
- for(int j = C[i].size() - 1; j; --j)
- C[i][j] -= C[i][j - 1];
- }
- int rt = 0;
- for(int i = 0; i < n; ++i) {
- if(C[i].size() > 1)
- rt = inc(rt, 0, n, i, 1);
- }
- priority_queue<qnode> Q;
- auto push = [&](long long has, long long cost, int rt) {
- if(T[rt].first >= n || rt == 0) return;
- qnode node;
- node.root = rt;
- node.cost = cost;
- node.has = has;
- if(taken.count(node.gethash())) return;
- taken[node.gethash()] = rt;
- Q.push(node);
- };
- long long ans = 0;
- long long cost = 0, has = 0;
- for(int i = 0; i < n; ++i) {
- cost += C[i][0];
- has += Val[i];
- }
- ans += cost;
- taken[has] = rt;
- k -= 1;
- //cerr << "HERE\n";
- push(has, cost, rt);
- for(int it = 0; it < k; ++it) {
- auto top = Q.top();
- long long cost = top.cost;
- int root = top.root;
- Q.pop();
- ans += top.getcost();
- //cerr << it << " " << top.getcost() << " " << top.gethash() << endl;
- auto p = T[root];
- long long nwcost = top.getcost();
- long long nwhash = top.gethash();
- int nwroot;
- if(p.second + 1 < C[p.first].size())
- nwroot = inc(root, 0, n, p.first, p.second + 1);
- else nwroot = inc(root, 0, n, p.first, -1);
- push(nwhash, nwcost, nwroot);
- root = inc(root, 0, n, p.first, -1);
- push(top.has, top.cost, root);
- }
- cout << ans << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement