CF1893C Freedom of Choice
CF1893C Freedom of Choice
首先算出
于是
如果
如果
这样可以算出
为了避免复杂度退化为 map<long long, vector<int>> 维护;以及对每个 map<pair<int, long long>, long long> 维护。
时间复杂度线性对数。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdi = pair<double, int>;
using pdd = pair<double, double>;
using ull = unsigned long long;
#define ppc(x) __builtin_popcount(x)
#define clz(x) __builtin_clz(x)
bool Mbe;
// mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
mt19937_64 rnd(1064);
int rd(int l, int r) {return rnd() % (r - l + 1) + l;}
constexpr int mod = 998244353;
void addt(int &x, int y) {x += y, x >= mod && (x -= mod);}
int add(int x, int y) {return x += y, x >= mod && (x -= mod), x;}
int ksm(int a, int b) {
int s = 1;
while(b) {
if(b & 1) s = 1ll * s * a % mod;
a = 1ll * a * a % mod, b >>= 1;
}
return s;
}
constexpr int Z = 1e6 + 5;
int fc[Z], ifc[Z];
int bin(int n, int m) {
if(n < m) return 0;
return 1ll * fc[n] * ifc[m] % mod * ifc[n - m] % mod;
}
void init_fac(int Z) {
for(int i = fc[0] = 1; i < Z; i++) fc[i] = 1ll * fc[i - 1] * i % mod;
ifc[Z - 1] = ksm(fc[Z - 1], mod - 2);
for(int i = Z - 2; ~i; i--) ifc[i] = 1ll * ifc[i + 1] * (i + 1) % mod;
}
// ---------- templates above ----------
constexpr int N = 1e5 + 5;
ll m, n[N], l[N], r[N], sc[N];
vector<ll> c[N], a[N];
void mian() {
cin >> m;
ll suml = 0, sumr = 0, sumn = 0;
map<ll, vector<int>> mp;
map<pair<int, ll>, ll> mp2;
for(int i = 1; i <= m; i++) {
vector<ll> ().swap(c[i]);
vector<ll> ().swap(a[i]);
cin >> n[i] >> l[i] >> r[i], sc[i] = 0;
sumn += n[i], suml += l[i], sumr += r[i];
c[i].resize(n[i]);
a[i].resize(n[i]);
for(int j = 0; j < n[i]; j++) cin >> a[i][j], mp[a[i][j]].push_back(i);
for(int j = 0; j < n[i]; j++) cin >> c[i][j], sc[i] += c[i][j];
for(int j = 0; j < n[i]; j++) mp2[{i, a[i][j]}] = c[i][j];
}
if(sumn < sumr - suml + 1) {
cout << 0 << "\n";
return;
}
ll ans = LONG_LONG_MAX;
for(ll cnt = suml; cnt <= sumr; cnt++) {
ll tot = sumr, res = 0;
vector<int> index = mp[cnt];
for(int i : index) {
tot -= r[i];
ll ctr = sc[i] - mp2[{i, cnt}];
if(ctr < l[i]) res += l[i] - ctr, ctr = l[i];
tot += min(ctr, r[i]);
}
ans = min(ans, res + max(0ll, cnt - tot));
}
cout << ans << "\n";
}
bool Med;
int main() {
fprintf(stderr, "%.3lf MB\n", (&Mbe - &Med) / 1048576.0);
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
cin >> T;
while(T--) mian();
cerr << 1e3 * clock() / CLOCKS_PER_SEC << " ms\n";
return 0;
}