ll n, m; pair<ll, ll> cow[maxn], grass[maxn]; multiset<ll> cow_set;
intmain(){ cin >> n >> m; for (int i = 1; i <= n; i ++) cin >> cow[i].first >> cow[i].second; for (int i = 1; i <= m; i ++) cin >> grass[i].first >> grass[i].second; sort(cow + 1, cow + 1 + n); sort(grass + 1, grass + 1 + m);
ll ans = 0; for (int grass_i = 1, cow_i = 0; grass_i <= m; grass_i ++) { ll now_grass_cost = grass[grass_i].first; ll now_grass_quality = grass[grass_i].second; for (int i = cow_i + 1; i <= n && cow[i].first <= now_grass_cost; i ++) { // 符号:将序排列 cow_set.insert(-cow[i].second); cow_i ++; } set<ll>::iterator iter = cow_set.lower_bound(-now_grass_quality); // 草品质达到 if (iter != cow_set.end()) { cow_set.erase(iter); ans += now_grass_cost; } } // 如果还有牛剩下来 -> 这些牛的要求没有被满足 -> 答案为-1 if (!cow_set.empty()) ans = -1; cout << ans << endl; }
P5021 赛道修建[NOIP2018-D1T3]
题目描述
$C$城将要举办一系列的赛车比赛。在比赛前,需要在城内修建$m$条赛道。
$C$城一共有$n$个路口,这些路口编号为$1,2,…,n$,有 n−1n-1n−1 条适合于修建赛道的双向通行的道路,每条道路连接着两个路口。其中,第 iii 条道路连接的两个路口编号为$a_i$和$b_i$,该道路的长度为$l_i$。借助这 n−1n-1n−1 条道路,从任何一个路口出发都能到达其他所有的路口。
ll dfs(ll u, ll p){ multiset<ll> s; for (ll e = head[u]; e != 0; e = g[e].next) { ll v = g[e].to; if (v != p) { ll alpha = dfs(v, u) + g[e].w; if (alpha < t) s.insert(alpha); else num --; } } ll ret = 0; while (!s.empty()) { multiset<ll>::iterator iter_1 = s.begin(); ll x = *iter_1; s.erase(iter_1); multiset<ll>::iterator iter_2 = s.lower_bound(t - x); if (iter_2 != s.end()) s.erase(iter_2), num --; else ret = max(ret, x); } return ret; }
intmain(){ cin >> n >> m; ll sum = 0; for (ll i = 1; i < n; i ++) { ll u, v, w; cin >> u >> v >> w; add_edge(u, v, w); add_edge(v, u, w); sum += w; } ll r = sum / m + 1; ll l = 0; while (r - l > 1) { t = (r + l) / 2; num = m; dfs(1, 0); if (num > 0) r = t; else l = t; } cout << l << endl; return0; }
constint maxn = 1000005; ll a[maxn]; int n, k; int kind = 0;
map<ll, int> cnt;
voidinc(int &j){ if (cnt[a[j]]++ == 0) kind ++; }
voiddec(int &j){ if (--cnt[a[j]] == 0) kind --; }
voidadv(int &i){ if (--cnt[a[i ++]] == 0) kind --; }
intmain(){ cin >> n >> k; for (int i = 1; i <= n; i ++) cin >> a[i]; int j = 1; int ans = 0; for (int i = 1; i <= n; adv(i)) { while (j <= n) { inc(j); if (kind > k + 1) { dec(j); break; } else j ++; } ans = max(ans, cnt[a[i]]); } cout << ans << endl; return0; }