답안 #957436

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
957436 2024-04-03T17:10:35 Z Nonoze Two Currencies (JOI23_currencies) C++17
0 / 100
12 ms 7784 KB
/*
*	Author: Nonoze
*	Created: Sunday 31/03/2024
*/
#include <bits/stdc++.h>
using namespace std;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template<class T> using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long ll;
#define int long long


#ifdef _IN_LOCAL
	#include <bits/DebugTemplate.h>
#else
	#define dbg(...) ;
#endif
#define sz(x) (int)(x.size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pb push_back
#define mp make_pair
#define fi first
#define se second

#define endl '\n'
#define endlfl '\n' << flush
#define quit(x) cout << x << endl, return;
const int MOD = 1e9+7;
const ll inf = 1e18;


template<typename T> constexpr bool cmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
template<typename T> constexpr bool cmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }


void solve();

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	int tt=1;
	// cin >> tt;
	while(tt--) solve();
	return 0;
}




int n, m, q;
vector<set<pair<int, int>>> adj;
vector<int> depth, nb, in, out;
vector<vector<int>> nxt;
vector<pair<int, int>> id;
vector<vector<int>> up;
int curr=0, toadd=-1;

void dfs(int s, int prec=-1) {
	id.push_back({s, 0}), in[s]=curr++;
	for (auto u: adj[s]) {
		if (u.fi==prec) continue;
		if (id.back().first==s) nxt[curr-1].push_back(u.se);
		if (toadd!=-1) nxt[toadd].push_back(u.se), toadd=-1;
		nb[u.fi]=nb[s]+(u.se?1:0);
		depth[u.fi]=depth[s]+1;
		up[u.fi][0]=s;
		for (int i=1; i<20; i++) {
			up[u.fi][i]=up[ up[u.fi][i-1] ][i-1];
		}
		dfs(u.fi, s);
		nxt[curr-1].push_back(-u.se);
		toadd=curr-1;
	}
	if (sz(adj)<=2) toadd=-1;
	id.push_back({s, 1}), out[s]=curr++;
}

int get_lca(int a, int b) {
	if (depth[a]<depth[b]) swap(a, b);
	int k=depth[a]-depth[b];
	for (int i=0; i<20; i++) {
		if (k&(1<<i)) {
			a=up[a][i];
		}
	}
	if (a==b) return a;
	for (int i=19; i>=0; i--) {
		if (up[a][i]!=up[b][i]) {
			a=up[a][i];
			b=up[b][i];
		}
	}
	return up[a][0];
}


vector<int> vaut, contains, sqr, nbelements;
int tot=0, squarevaut;
int ask(int a, int b) {
	int comp=0, empl=0;
	for (; empl<sz(sqr) && sqr[empl]<=b; empl++) {
		b-=sqr[empl];
		comp+=nbelements[empl];
	}
	for (empl*=squarevaut; empl<sz(contains) && vaut[empl]*contains[empl]<=b; empl++) {
		b-=contains[empl]*vaut[empl];
		comp+=contains[empl];
	}

	return max(-1LL, a-tot+comp);
}


void resolve() {

	map<int, int> mp;
	for (int i=0; i<n; i++) {
		for (auto u: adj[i]) {
			if (u.fi<i) continue;
			mp[u.se]++;
		}
	}
	mp[0]++;
	int compteur=0;
	for (auto &u: mp) {
		int sz=u.se;
		u.se=compteur; compteur+=sz;
	}
	squarevaut=sqrt(compteur);
	vaut.resize(compteur, 0), contains.resize(compteur, 0), sqr.resize(squarevaut+5, 0), nbelements.resize(squarevaut+5, 0);
	for (int i=0; i<n; i++) {
		auto temp=adj[i];
		for (auto &u: temp) {
			if (u.fi<i) continue;
			vaut[mp[u.se]]=u.se;
			adj[i].erase({u.fi, u.se});
			adj[i].insert({u.fi, mp[u.se]});
			adj[u.fi].erase({i, u.se});
			adj[u.fi].insert({i, mp[u.se]++});
		}
	}


	depth.resize(n), nb.resize(n), in.resize(n), out.resize(n);
	nxt.resize(2*n), up.resize(n, vector<int>(20));
	dfs(0);
	// dbg(in, out, nxt);

	vector<int> answers(q);
	vector<pair<vector<int>, int>> queries;
	for (int i=0; i<q; i++) {
		int s, t, a, b; cin >> s >> t >> a >> b;
		s--, t--;
		if (in[s]>in[t]) swap(s, t);
		int l, r, lca=get_lca(s, t);
		if (lca==s) l=in[s], r=in[t];
		else l=out[s], r=in[t];
		queries.push_back({{l, r, lca, a, b}, i});
	}
	int square=sqrt(2*n);
	sort(all(queries), [&](auto &a, auto &b){
		if (a.fi[0]/square!=b.fi[0]/square) return a.fi[0]/square<in[b.fi[0]]/square;
		return a.fi[1]<b.fi[1];
	});
	int left=0, right=0;
	for (int i=0; i<q; i++) {
		int l=queries[i].fi[0], r=queries[i].fi[1], lca=queries[i].fi[2];
		while (right<r) {
			for (auto u: nxt[right]) {
				if (!u) continue;
				int empl=abs(u), sign=(contains[empl]?-1:1);
				sqr[empl/squarevaut]+=vaut[empl]*sign;
				contains[empl]+=sign;
				nbelements[empl/squarevaut]+=sign;
				tot+=sign;
			}
			right++;
		}
		while (left>l) {
			left--;
			for (auto u: nxt[left]) {
				if (!u) continue;
				int empl=abs(u), sign=(contains[empl]?-1:1);
				sqr[empl/squarevaut]+=vaut[empl]*sign;
				contains[empl]+=sign;
				nbelements[empl/squarevaut]+=sign;
				tot+=sign;
			}
		}
		while (left<l) {
			for (auto u: nxt[left]) {
				if (!u) continue;
				int empl=abs(u), sign=(contains[empl]?-1:1);
				sqr[empl/squarevaut]+=vaut[empl]*sign;
				contains[empl]+=sign;
				nbelements[empl/squarevaut]+=sign;
				tot+=sign;
			}
			left++;
		}
		while (right>r) {
			right--;
			for (auto u: nxt[right]) {
				if (!u) continue;
				int empl=abs(u), sign=(contains[empl]?-1:1);
				sqr[empl/squarevaut]+=vaut[empl]*sign;
				contains[empl]+=sign;
				nbelements[empl/squarevaut]+=sign;
				tot+=sign;
			}
		}
		answers[queries[i].se]=ask(queries[i].fi[3], queries[i].fi[4]);
	}
	for (auto u: answers) cout << u << endl;
}


void solve() {
	cin >> n >> m >> q;
	adj.resize(n);
	bool sub3=true;
	vector<pair<int, int>> edges;
	for (int i=1; i<n; i++) {
		int u, v; cin >> u >> v;
		edges.push_back({--u, --v});
		if (v!=u+1) sub3=false;
		adj[u].insert({v, 0});
		adj[v].insert({u, 0});
	}
	vector<stack<int>> updates(n-1);
	for (int i=0; i<m; i++) {
		int p, c; cin >> p >> c;
		updates[--p].push(c);
	}
	for (int i=0; i<sz(updates); i++) {
		if (updates[i].empty()) continue;
		auto act=updates[i];
		int u=edges[i].fi, v=edges[i].se;
		adj[u].erase({v, 0}); adj[v].erase({u, 0});
		adj[u].insert({v, act.top()});
		adj[v].insert({u, act.top()});
		int weightbase=act.top(); act.pop();
		while (!act.empty()) {
			int weight=act.top(); act.pop();
			adj[u].erase({v, weightbase}); adj[v].erase({u, weightbase});
			adj[u].insert({n, weight});
			adj.push_back({});
			adj[n].insert({u, weight});
			adj[v].insert({n, weightbase});
			adj[n].insert({v, weightbase});
			u=n;
			n++;
		}
	}
	resolve();
}

Compilation message

currencies.cpp: In function 'void resolve()':
currencies.cpp:172:47: warning: unused variable 'lca' [-Wunused-variable]
  172 |   int l=queries[i].fi[0], r=queries[i].fi[1], lca=queries[i].fi[2];
      |                                               ^~~
currencies.cpp: In function 'void solve()':
currencies.cpp:226:7: warning: variable 'sub3' set but not used [-Wunused-but-set-variable]
  226 |  bool sub3=true;
      |       ^~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 1 ms 456 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Runtime error 7 ms 6488 KB Execution killed with signal 11
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
2 Runtime error 8 ms 6712 KB Execution killed with signal 11
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 12 ms 4124 KB Output is correct
3 Correct 12 ms 3932 KB Output is correct
4 Runtime error 8 ms 7784 KB Execution killed with signal 11
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 1 ms 456 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Runtime error 7 ms 6488 KB Execution killed with signal 11
6 Halted 0 ms 0 KB -