Submission #1308148

#TimeUsernameProblemLanguageResultExecution timeMemory
1308148sweetwibu2k8Two Currencies (JOI23_currencies)C++20
100 / 100
573 ms30312 KiB
#include <bits/stdc++.h>
using namespace std;

#define endl "\n"
#define fi first
#define se second
#define pb push_back
#define p_q priority_queue
#define bit(n, i) (((n)>>(i))&1)
#define all(x) x.begin(), x.end()

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,int> pli;
typedef vector <vector <int> > vvi;

const int M = 1e5 + 6;
const int mod = 1e9 + 7;
const int inf = 1e9 + 7;

void maximize (int &a, int b) { if (a < b) a = b; }
void minimize (int &a, int b) { if (a > b) a = b; }
void add (int &a, int b) { a += b; if (a >= mod) a -= mod; }
void del (int &a, int b) { a -= b; if (a < 0) a += mod; }

int n, m, q;
vector <int> g[M];
pii e[M], t[M];
int cost[M], in[M], out[M], tt[M], dem[M];
int anc[M][18], depth[M];
int d[M], ini[M], Lca[M];
int timedfs = 0;
int L[M], R[M], MID[M];
ll ans[M];
struct query 
{
	int s, t;
	ll x, y;
} Q[M];

struct Fenwick
{
	ll f[M];
	int n;
	
	void resize (int x) { n = x; for (int i = 1; i <= n; i ++) f[i] = 0; }
	void update (int i, int val) { while (i <= n) { f[i] += val; i += i & (-i); } }
	ll GET (int i) { ll res = 0; while (i > 0) { res += f[i]; i -= i & (-i); } return res; }
	ll get (int l, int r) { return GET (r) - GET (l - 1); }
} BIT, CNT;

void dfs (int u, int parent)
{
	in[u] = ++ timedfs;
	tt[timedfs] = u;
	
	for (int &v : g[u])
	{
		if (v == parent) continue;
		anc[v][0] = u;
		depth[v] = depth[u] + 1;
		dfs (v, u);
	}
	
	out[u] = timedfs;
}

int LCA (int u, int v)
{
	if (depth[u] < depth[v]) swap (u, v);
	while (depth[u] > depth[v])
	{
		int k = __lg (depth[u] - depth[v]);
		u = anc[u][k];
	}
	if (u == v) return u;
	
	int k = __lg (depth[u]);
	while (k >= 0)
	{
		if (anc[u][k] != anc[v][k])
		{
			u = anc[u][k];
			v = anc[v][k];
		}
		k --;
	}
	return anc[u][0];
}

void prework (int u, int parent)
{
	for (int &v : g[u])
	{
		if (v == parent) continue;
		d[v] += d[u];
		prework (v, u);
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
//	freopen (".inp", "r", stdin);
//	freopen (".out", "w", stdout);
	
	cin >> n >> m >> q;
	for (int i = 1; i < n; i ++)
	{
		int u, v; cin >> u >> v;
		g[u].pb (v);
		g[v].pb (u);
		e[i] = {u, v};
	}
	for (int i = 1; i <= m; i ++)
	{
		int p, c; cin >> p >> c;
		t[i] = {c, p};
	}
	
	for (int i = 1; i <= q; i ++)
	{
		int s, t; ll x, y; cin >> s >> t >> x >> y;
		Q[i] = {s, t, x, y};
		ans[i] = -1;
	}
	
	dfs (1, 0);
	int kmax = __lg (n);
	for (int k = 1; k <= kmax; k ++)
		for (int i = 1; i <= n; i ++)
			anc[i][k] = anc[anc[i][k - 1]][k - 1];
	for (int i = 1; i < n; i ++)
		if (e[i].fi != anc[e[i].se][0]) swap (e[i].fi, e[i].se);
	
	sort (t + 1, t + m + 1);
	for (int i = 1; i <= m; i ++)
	{
		int id = e[t[i].se].se;
		d[id] ++;
	}
		
	prework (1, 0);
	for (int i = 1; i <= q; i ++)
	{
		int u = Q[i].s, v = Q[i].t;
		int lca = LCA (u, v);
		ini[i] = d[u] + d[v] - 2 * d[lca];
		Lca[i] = lca;
	}
	
	for (int i = 1; i <= q; i ++)
		L[i] = 0, R[i] = m;
	
	while (true)
	{
		vector <int> Query;
		for (int i = 1; i <= q; i ++)
		{
			if (L[i] > R[i]) continue;
			MID[i] = (L[i] + R[i]) / 2;
			Query.pb (i);
		}
		
		if (Query.empty()) break;
		sort (all (Query), [] (int a, int b) {
			return MID[a] < MID[b];
		});
		
		
		BIT.resize (n + 2);
		CNT.resize (n + 2);
		int pt = 1;
		for (int &i : Query)
		{
			int ss = Q[i].s, tt = Q[i].t;
			ll x = Q[i].x, y = Q[i].y;
			while (pt <= MID[i])
			{
				int v = e[t[pt].se].se, val = t[pt].fi;
				BIT.update (in[v], val);
				BIT.update (out[v] + 1, -val);
				CNT.update (in[v], 1);
				CNT.update (out[v] + 1, -1);
				pt ++;
			}
			ll lmao = BIT.GET (in[ss]) + BIT.GET (in[tt]) - 2 * BIT.GET (in[Lca[i]]);
			ll sl = CNT.GET (in[ss]) + CNT.GET (in[tt]) - 2 * CNT.GET (in[Lca[i]]);
			if (lmao <= y)
			{
				ans[i] = max (ans[i], x - ini[i] + sl);
				L[i] = MID[i] + 1;
			}
			else R[i] = MID[i] - 1;
		}
	}
	
	for (int i = 1; i <= q; i ++)
		cout << ans[i] << endl;
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...