Submission #1185599

#TimeUsernameProblemLanguageResultExecution timeMemory
1185599jahongirTwo Currencies (JOI23_currencies)C++20
68 / 100
5029 ms71864 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

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

#define ll long long
#define pi pair<int,int>
#define pb push_back
#define all(a) a.begin(),a.end()

const int mxn = 1e5+10;
vector<pi> g[mxn];
vector<ll> cost[mxn];

int par[mxn], head[mxn], heavy[mxn];
int pos[mxn], dep[mxn], val[mxn], cur_pos;
int inper[mxn];

int dfs(int u, int p){
	par[u] = p, dep[u] = dep[p] + 1;
	int sz = 1, mx = 0;

	for(auto [v,i] : g[u]) if(v!=p){
		int vsz = dfs(v,u); sz += vsz;
		val[v] = i;
		if(mx < vsz)
			mx = vsz, heavy[u] = v;
	}
	
	return sz;	
}

void decompose(int u, int h){
	inper[cur_pos] = val[u];
	head[u] = h, pos[u] = cur_pos++;

	if(heavy[u]) decompose(heavy[u],h);

	for(auto [v,i] : g[u]) if(v!=par[u] && v!=heavy[u])
		decompose(v,v);
}



struct SegTree{
	int sz; vector<ll> st[3*mxn];
	vector<ll> pref[3*mxn];

	void build(int i, int l, int r){
		if(l==r){
			st[i] = cost[inper[l]];
			pref[i] = st[i];
			for(int j = 1; j < st[i].size(); j++){
				pref[i][j] += pref[i][j-1];
			}
			return;
		}
		int m = (l+r)>>1;
		build(i<<1,l,m); build(i<<1|1,m+1,r);
		merge(all(st[i<<1]),all(st[i<<1|1]),back_inserter(st[i]));
		

		pref[i] = st[i];
		for(int j = 1; j < st[i].size(); j++)
			pref[i][j] += pref[i][j-1];
	}

	void init(int n){
		sz = n;
		build(1,0,sz-1);
	}

	pair<ll,ll> query(int i, int l, int r, int s, int e, ll x){
		if(r < s || l > e) return {0ll,0ll};
		if(s <= l && r <= e){
			int ind = upper_bound(all(st[i]),x) - st[i].begin();
			return {ind?pref[i][ind-1]:0ll , ind };
		}
		int m = (l+r)>>1;
		auto s1 = query(i<<1,l,m,s,e,x);
		auto s2 = query(i<<1|1,m+1,r,s,e,x);
		return {s1.first + s2.first, s1.second + s2.second };
	}

	pair<ll,ll> query(int l, int r, ll x){
		if(l > r) return {0ll,0ll};
		return query(1,0,sz-1,l,r,x);
	}
}st;

void apply(pair<ll,ll> &a, pair<ll,ll> b){
	a.first = a.first + b.first;
	a.second = a.second + b.second;
}


pair<ll,ll> query(int u, int v, ll mid){
	pair<ll,ll> res = {0ll,0ll};
	for(; head[u] != head[v]; v = par[head[v]]){
		if(dep[head[u]] > dep[head[v]]) swap(u,v);
		apply(res,st.query(pos[head[v]],pos[v],mid));
	}
	if(dep[u] > dep[v]) swap(u,v);
	apply(res,st.query(pos[u]+1,pos[v],mid));
	return res;
}


void solve(){
	int n,m,q; scanf("%d %d %d",&n,&m,&q);

	for(int i = 1; i < n; i++){
		int u,v; scanf("%d %d",&u,&v);
		g[u].pb({v,i});
		g[v].pb({u,i});
	}

	for(int i = 0; i < m; i++){
		int p,c; scanf("%d %d",&p,&c);
		cost[p].pb(c);
	}

	for(int i = 1; i < n; i++)
		sort(all(cost[i]));

	
	dfs(1,1); decompose(1,1);
	st.init(n);
	
	

	while(q--){
		int u,v; ll x,y;
		scanf("%d %d %lld %lld",&u,&v,&x,&y);
		
		ll l = 0, r = y+2;

		while(l+1 < r){
			ll mid = (l+r)>>1;
			auto tmp = query(u,v,mid);
			if(tmp.first <= y) l = mid;
			else r = mid;
		}

		pair<ll,ll> res = query(u,v,l);
		ll total = query(u,v,2e9).second;
		
		total -= res.second; y -= res.first; total -= y / (l+1);
		printf("%lld\n",max(-1ll,x - total));
	}
}

int main(){

	//freopen("censor.in","r",stdin);
	//freopen("censor.out","w",stdout);

	int t = 1;
	while(t--) solve();
}

Compilation message (stderr)

currencies.cpp: In function 'void solve()':
currencies.cpp:115:25: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  115 |         int n,m,q; scanf("%d %d %d",&n,&m,&q);
      |                    ~~~~~^~~~~~~~~~~~~~~~~~~~~
currencies.cpp:118:31: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  118 |                 int u,v; scanf("%d %d",&u,&v);
      |                          ~~~~~^~~~~~~~~~~~~~~
currencies.cpp:124:31: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  124 |                 int p,c; scanf("%d %d",&p,&c);
      |                          ~~~~~^~~~~~~~~~~~~~~
currencies.cpp:139:22: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  139 |                 scanf("%d %d %lld %lld",&u,&v,&x,&y);
      |                 ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...