제출 #1364083

#제출 시각아이디문제언어결과실행 시간메모리
1364083vlomaczkCollecting Stamps 4 (JOI25_stamps4)C++20
100 / 100
1762 ms248968 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

ll inf = 4e18;

ll base = 1<<22;
vector<ll> T(2*base);

void update(ll x, ll val) {
	x+=base;
	T[x] = val;
	x/=2;
	while(x > 0) {
		T[x] = T[x+x] + T[x+x+1];
		x/=2;
	}
}

ll query(ll a, ll b) {
	if(a > b) return 0;
	if(a==b) return T[a+base];
	a+=base-1;
	b+=base+1;
	ll res = 0;
	while(a/2 != b/2) {
		if(a%2 ==0) res += T[a+1];
		if(b%2 ==1) res += T[b-1];
		a/=2; b/=2;
	}
	return res;
}

signed main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	ll n, X;
	cin >> n >> X;
	n*=2;
	vector<ll> a(n), c(n);
	for(auto &x : a) cin >> x;
	for(auto &x : c) cin >> x;
	vector<ll> res(n);
	vector<vector<ll>> nxt(n+1);
	for(ll i=0; i<n; ++i) nxt[a[i]].push_back(i);
	for(ll i=0; i<n; ++i) nxt[a[i]].push_back(n+i);
	ll wynik = 0;
	vector<ll> seen(n+1);
	ll ile_puste = 0;
	for(ll i=0; i<n; ++i) {
		if(seen[a[i]]) {
			update(i,1);
			ile_puste++;
		} else {
			seen[a[i]] = 1;
			wynik += n/2 - ile_puste;
		}
	}
	for(auto &x : nxt) {
		reverse(x.begin(), x.end());
		x.pop_back();
	}
	res[0] = wynik;
	ll ile_pelne = n/2;
	for(ll i=0; i<n-1; ++i) {
		ll nowy = nxt[a[i]].back();
		nxt[a[i]].pop_back();

		ll przed = query(0, nowy-1);
		ll pp = nowy - przed;

		wynik -= przed;
		wynik += (ll)ile_pelne - pp;
		update(i+n, 1);
		update(nowy, 0);
		ile_pelne++;
		res[i+1] = wynik;
	}

	ll q; cin >> q;
	if(q==1) {
		ll x; cin >> x;
		ll W = inf;
		for(ll i=0; i<n; ++i) W = min(W, c[i] + X*max(0LL, x-res[i]));
		cout << W << "\n";
		return 0;
	}

	vector<ll> ans(q);
	vector<pair<ll, ll>> sweep;
	for(ll t=0; t<q; ++t) {
		ll xx; cin >> xx;
		sweep.push_back({xx, t});
	}
	for(ll i=0; i<n; ++i) {
		sweep.push_back({res[i], -i-1});
	}
	set<pair<ll, ll>> lowest;
	for(ll i=0; i<n; ++i) lowest.insert({c[i], i});
	sort(sweep.begin(), sweep.end());
	pair<ll, ll> best = {inf, -1}; // koszt, idx
	for(auto[x, t] : sweep) {
		if(t < 0) {
			t*=-1;
			t--;
			best = min<pair<ll, ll>>({best.first + (x - best.second)*X, x}, {c[t], x});
			lowest.erase({c[t], t});
		} else {
			ll L = (lowest.size() ? lowest.begin()->first : inf);
			ll val = best.first + X * (x-best.second);
			ans[t] = min(val, L);
		}
	}
	for(ll t=0; t<q; ++t) cout << ans[t] << "\n";

	return 0;
}

#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…