이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
const bool typetest = 0;
const int N = 2e5 + 5;
struct Edge
{
int u, v;
ll w;
Edge(const int &u = 0, const int &v = 0, const ll &w = 0) : u(u), v(v), w(w)
{
}
bool operator<(const Edge &a) const
{
return w < a.w;
}
};
struct FenwickTree
{
vector<ll> a;
int n;
FenwickTree(const int &n = 0)
{
a.resize(n + 1);
this->n = n;
}
void Clear()
{
fill(a.begin(), a.end(), 0);
}
void Update(int p, int v)
{
for (; p <= n; p += p & -p)
a[p] += v;
}
ll Get(int p)
{
ll ans(0);
for (; p > 0; p -= p & -p)
ans += a[p];
return ans;
}
ll Get(int l, int r)
{
return Get(r) - Get(l - 1);
}
};
struct RangeFen
{
FenwickTree s1, s2;
int n;
RangeFen(const int &n = 0)
{
this->n = n;
s1 = FenwickTree(n);
s2 = FenwickTree(n);
}
void Clear()
{
s1.Clear();
s2.Clear();
}
void Update(int l, int r, ll v)
{
s1.Update(l, v);
s1.Update(r + 1, -v);
s2.Update(l, (l - 1) * v);
s2.Update(r + 1, -v * r);
}
ll Get(int p)
{
return s1.Get(p) * p - s2.Get(p);
}
ll Get(int l, int r)
{
return Get(r) - Get(l - 1);
}
} f;
struct dsu
{
int par[N];
dsu()
{
memset(par, -1, sizeof par);
}
int findpar(int v)
{
return par[v] < 0 ? v : par[v] = findpar(par[v]);
}
bool merge(int u, int v)
{
u = findpar(u);
v = findpar(v);
if (u == v)
return false;
if (par[u] < par[v])
swap(u, v);
par[v] += par[u];
par[u] = v;
return true;
}
} g;
int n, m, c;
int u[N], v[N], p[N], q[N], r[N], s[N];
vector<int> x, y;
vector<ll> ans, res;
vector<vector<int>> pos;
vector<vector<pair<int, int>>> in, out;
vector<Edge> e;
void Read()
{
cin >> n >> m >> c;
x.reserve(m * 2 + n);
y.reserve(m * 2 + n);
for (int i = 1; i <= n; ++i)
{
cin >> u[i] >> v[i];
x.push_back(u[i]);
y.push_back(v[i]);
}
for (int i = 1; i <= m; ++i)
{
cin >> p[i] >> q[i] >> r[i] >> s[i];
x.push_back(p[i]);
x.push_back(r[i]);
y.push_back(q[i]);
y.push_back(s[i]);
}
}
void Sort(vector<int> &s)
{
sort(s.begin(), s.end());
s.resize(unique(s.begin(), s.end()) - s.begin());
}
int Find(vector<int> &s, int v)
{
return lower_bound(s.begin(), s.end(), v) - s.begin();
}
void Sort_pos()
{
for (int i = 0; i < (int)pos.size(); ++i)
sort(pos[i].begin(), pos[i].end(), [&](const int &x, const int &y) {
return v[x] < v[y];
});
}
void Prog(int sz, vector<int> &y)
{
for (int i = 0; i < (int)sz; ++i)
{
for (auto j : in[i])
f.Update(Find(y, j.first) + 1, Find(y, j.second), 1);
for (int j = 0; j < (int)pos[i].size(); ++j)
{
int t = j + 1;
while (t < (int)pos[i].size() && f.Get(Find(y, v[pos[i][j]]) + 1, Find(y, v[pos[i][t]])) == 0)
{
e.emplace_back(pos[i][t], pos[i][t - 1], v[pos[i][t]] - v[pos[i][t - 1]]);
++t;
}
j = t - 1;
}
for (auto j : out[i])
f.Update(Find(y, j.first) + 1, Find(y, j.second), -1);
}
}
void Kruskal()
{
sort(e.begin(), e.end());
ans.reserve((int)e.size() + 1);
ans.push_back(0);
for (auto i : e)
if (g.merge(i.u, i.v)){
ans.push_back(i.w);
}
res.resize(ans.size(), 0);
for (int i = 1; i < (int)ans.size(); ++i)
res[i] = res[i - 1] + ans[i];
}
void Solve()
{
Sort(x);
Sort(y);
f = RangeFen((int)max(x.size(), y.size()));
pos.resize(max(x.size(), y.size()));
in.resize(max(x.size(), y.size()));
out.resize(max(x.size(), y.size()));
for (int i = 1; i <= n; ++i)
pos[Find(x, u[i])].push_back(i);
Sort_pos();
for (int i = 1; i <= m; ++i)
{
in[Find(x, p[i])].push_back({q[i], s[i]});
out[Find(x, r[i])].push_back({q[i], s[i]});
}
Prog(x.size(), y);
for (int i = 0; i < (int)x.size(); ++i)
{
pos[i].clear();
in[i].clear();
out[i].clear();
}
for (int i = 1; i <= n; ++i)
{
pos[Find(y, v[i])].push_back(i);
swap(u[i], v[i]);
}
Sort_pos();
for (int i = 1; i <= m; ++i)
{
in[Find(y, q[i])].push_back({p[i], r[i]});
out[Find(y, s[i])].push_back({p[i], r[i]});
}
Prog(y.size(), x);
Kruskal();
while (c--)
{
int k;
ll b;
cin >> b >> k;
if (k < n - (int)ans.size() + 1)
{
cout << "-1\n";
continue;
}
k -= n - ans.size() + 1;
int j = max((int)(lower_bound(ans.begin() + 1, ans.end(), b) - ans.begin()), (int)ans.size() - k);
cout << res[j - 1] + b * (ans.size() - j) + (n - ans.size() + 1) * b << "\n";
}
}
int32_t main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t(1);
if (typetest)
cin >> t;
for (int _ = 1; _ <= t; ++_)
{
Read();
Solve();
}
}
# | 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... |