#include<bits/stdc++.h>
using namespace std;
#define task "a"
#define se second
#define fi first
#define ll long long
#define ii pair<int, int>
#define tp tuple<int, int, int>
#define int ll
const long mxN = 2e5 + 7;
const ll inf = 1e18 + 7;
int tree[mxN * 12], lazy[mxN * 12], dsu[mxN], n, m, q, cnt[mxN * 3];
vector<int> vir;
ii l[mxN], r[mxN];
tp a[mxN], forbid[mxN * 2];
vector<tp> Edge;
vector<ii> querry[mxN];
ll ans[mxN * 3], cost[mxN * 3];
void Reset(int j = 1, int l = 0, int r = vir.size() - 1)
{
tree[j] = lazy[j] = 0;
if (l == r)
return;
int mid = (l + r) / 2;
Reset(j * 2, l, mid);
Reset(j * 2 + 1, mid + 1, r);
}
void Down(int j)
{
tree[j * 2] += lazy[j];
tree[j * 2 + 1] += lazy[j];
lazy[j * 2] += lazy[j];
lazy[j * 2 + 1] += lazy[j];
lazy[j] = 0;
}
void Upd(int u, int v, int val, int j = 1, int l = 0, int r = vir.size() - 1)
{
if (u > vir[r] || vir[l] > v)
return;
if (u <= vir[l] && vir[r] <= v)
{
tree[j] += val;
lazy[j] += val;
return;
}
Down(j);
int mid = (l + r) / 2;
Upd(u, v, val, j * 2, l, mid);
Upd(u, v, val, j * 2 + 1, mid + 1, r);
tree[j] = max(tree[j * 2], tree[j * 2 + 1]);
}
int Get(int u, int v, int j = 1, int l = 0, int r = vir.size() - 1)
{
if (u > vir[r] || vir[l] > v)
return 0;
if (u <= vir[l] && vir[r] <= v)
return tree[j];
Down(j);
int mid = (l + r) / 2;
return max(Get(u, v, j * 2, l, mid), Get(u, v, j * 2 + 1, mid + 1, r));
}
int Find(int j)
{
if (dsu[j] == j)
return j;
else
return dsu[j] = Find(dsu[j]);
}
bool Union(int u, int v)
{
u = Find(u);
v = Find(v);
if (u == v)
return 0;
dsu[v] = u;
return 1;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
//freopen(task".INP", "r", stdin);
//freopen(task".OUT", "w", stdout);
cin >> n >> m >> q;
for (int i = 1; i <= n; i++)
{
int u, v;
cin >> u >> v;
a[i] = {u, v, i};
dsu[i] = i;
}
for (int i = 1; i <= m; i++)
cin >> l[i].fi >> l[i].se >> r[i].fi >> r[i].se;
//Sweepline tao canh
for (int u = 0; u <= 1; u++)
{
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; i++)
vir.push_back(get<2>(a[i]));
for (int i = 1; i <= m; i++)
{
forbid[i] = {l[i].fi, i, 1};
forbid[i + m] = {r[i].fi, i, -1};
vir.push_back(l[i].se);
vir.push_back(r[i].se);
}
sort(forbid + 1, forbid + 2 * m + 1);
sort(vir.begin(), vir.end());
vir.erase(unique(vir.begin(), vir.end()), vir.end());
int ctr = 1;
for (int i = 2; i <= n; i++)
{
while (ctr <= 2 * m && get<0>(forbid[ctr]) <= get<0>(a[i]))
{
int id = get<1>(forbid[ctr]);
Upd(l[id].se, r[id].se, get<2>(forbid[ctr]));
ctr++;
}
if (get<0>(a[i]) != get<0>(a[i - 1]))
continue;
if (!Get(get<1>(a[i - 1]), get<1>(a[i])))
Edge.push_back({get<1>(a[i]) - get<1>(a[i - 1]), get<2>(a[i - 1]), get<2>(a[i])});
}
for (int i = 1; i <= n; i++)
swap(get<0>(a[i]), get<1>(a[i]));
for (int i = 1; i <= m; i++)
{
swap(l[i].fi, l[i].se);
swap(r[i].fi, r[i].se);
}
Reset();
vir.clear();
}
sort(Edge.begin(), Edge.end());
for (int i = 1; i <= q; i++)
{
cin >> cost[i] >> cnt[i];
ans[i] = inf;
if (cnt[i] == n)
ans[i] = cost[i] * cnt[i];
}
int num = n;
ll sum = 0;
for (tp i : Edge)
{
if (Union(get<1>(i), get<2>(i)))
{
num--;
sum += get<0>(i);
}
for (int i = 1; i <= q; i++)
{
if (cnt[i] >= num)
ans[i] = min(ans[i], sum + 1LL * num * cost[i]);
}
}
for (int i = 1; i <= q; i++)
{
if (ans[i] == inf)
cout << -1 << '\n';
else
cout << ans[i] << '\n';
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |