제출 #1123900

#제출 시각아이디문제언어결과실행 시간메모리
1123900tintingyn21Two Currencies (JOI23_currencies)C++20
10 / 100
5096 ms51888 KiB




// author : daohuyenchi



#ifdef LOCAL
    #include "D:\C++ Submit\debug.h"
#else
    #define debug(...)
#endif



#include <bits/stdc++.h>

using namespace std;

#define ull unsigned long long
#define db double
#define i32 int32_t
#define i64 int64_t
#define ll long long
//
#define fi first
#define se second


//                                      #define int long long    // consider carefully


//
#define pii pair <int, int>
#define pll pair <ll, ll>
#define PAIR make_pair
#define TUP make_tuple
//                                      TIME IS LIMITED ...
#define  rep(i, a, b) for (int i = (a), _b = (b); i <= _b; ++i)
#define repd(i, b, a) for (int i = (b), _a = (a); i >= _a; --i)
#define repv(v, H) for(auto &v: H)
//                                      REFLECT ON THE PAST ...
#define RESET(c, x) memset(c, x, sizeof(c))
#define MASK(i) (1LL << (i))
#define BIT(mask, i) (((mask) >> (i)) & 1LL)
#define ONBIT(mask, i) ((mask) | (1LL << (i)))
#define OFFBIT(mask, i) ((mask) &~ (1LL << (i)))
#define COUNTBIT __builtin_popcountll
//                                      30 / 1 / 2024 ? love is zero... start from zero
#define vi vector <int>
#define vll vector <ll>
#define Lower lower_bound
#define Upper upper_bound
#define all(v) (v).begin(), (v).end()
#define special(H) (H).resize(distance(H.begin(), unique(all(H))))
//
#define sp ' '
#define nl '\n'
#define EL { cerr << '\n'; }
#define yes "YES"
#define no "NO"
#define Log2(n) (63 - __builtin_clzll(n))
#define left __left__
#define right __right__
#define lps(id) ((id) << 1)
#define rps(id) ((id) << 1 | 1)

//____________________________________________________________________


template <class X, class Y> bool maximize(X &a, const Y &b)
{ if(a < b) return a = b, true; else return false; }

template <class X, class Y> bool minimize(X &a, const Y &b)
{ if(a > b) return a = b, true; else return false; }

template <class... T>
void print(T&&... n)
{ using exp = int[]; exp{ 0, (cerr << n << sp, 0)... }; cerr << nl; }

template <class T, class... C>
void assign(int n, T v, C&&... a)
{ using e = int[]; e { (a.assign(n, v), 0)...}; }

template <class... C>
void resize(int n, C&&... a)
{ using e = int[]; e { (a.resize(n), 0)...}; }

template <class T>
using vector2d = vector<vector<T>>;
template <class T>
using vector3d = vector<vector2d<T>>;

template <class T> int ssize(T &a) { return (int) a.size(); }


//____________________________________________________________________


mt19937 rng(chrono::steady_clock().now().time_since_epoch().count());

const long long MOD      = 1000000007;
// const int MOD[2] = {1000000009, 998244353};

template<class X> void modmize(X &x, long long cur_Mod = MOD) {
    if(x >= cur_Mod) x -= cur_Mod;
    if(x < 0) x += cur_Mod;
}

int mod_plus(int A, int B) { modmize(A += B); return A; }

const long long oo      = 1e18 + 7;
const long long LINF    = 1e18 + 7;
const int IINF          = 2e9;
const int nmax          = 2e5 + 10;
const int MAX           = 1e6;
const int base          = 311;
const double eps        = 1e-6;
const int block         = 500;
static const double PI  = acos(-1.0);

//____________________________________________________________________


int n, m, Q;
vector <int> G[nmax];


///////////////////////////////////////////////////////////////////////////////

struct LCA_Euler {
    int tour[nmax << 1];
    int timer = 0;
    int ein[nmax], dep[nmax];
    void dfs(int u, int par) {
        ein[u] = ++timer;
        dep[u] = dep[par] + 1;
        tour[timer] = u;
        repv (v, G[u]) {
            if (v == par) continue;
            dfs(v, u);
            tour[++timer] = u;
        }
    }

    int min_node(int u, int v) {
        return dep[u] <= dep[v] ? u : v;
    }

    int r_lca[nmax << 1][22];

    void build_lca() {

        dfs(1, 0);

        rep (i, 1, timer) {
            r_lca[i][0] = tour[i];
        }

        rep (k, 1, 18) {
            for (int i = 1; i + (1 << k) - 1 <= timer; ++i) {
                r_lca[i][k] = min_node(r_lca[i][k - 1], r_lca[i + (1 << (k - 1))][k - 1]);
            }
        }
    }

    int get_lca(int u, int v) {
        int l = ein[u];
        int r = ein[v];
        if (l > r) swap(l, r);
        int k = Log2(r - l + 1);
        return min_node(r_lca[l][k], r_lca[r - (1 << k) + 1][k]);
    }
} lca;

///////////////////////////////////////////////////////////////////////////////


array <ll, 4> qs[nmax];
int a[nmax];
pll c[nmax];
array <int, 2> ed[nmax];
int b[nmax];
int dep[nmax], ein[nmax], tour[nmax * 2], eout[nmax];
int timer = 0;
void dfs(int u, int p) {
	ein[u] = ++timer;
	tour[timer] = u;
	dep[u] = dep[p] + 1;
	repv (v, G[u]) {
		if (v == p) continue;
		dfs(v, u);
	}
	eout[u] = ++timer;
	tour[timer] = u;
}

int pf[nmax];

vector <int> List[nmax];
void dfs2(int u, int p) {
	pf[u] = pf[p] + ssize(List[u]);
	repv (v, G[u]) {
		if (v == p) continue;
		dfs2(v, u);
	}
}

struct Query {

	int l, r, anc, type, id;
	bool operator < (const Query &ot) {
		return TUP(l / block, r, id) < TUP(ot.l / block, ot.r, ot.id);
	}
};

Query query[nmax];
vector <int> zi;
int Lim;

int real_val(int x) {
	return zi[x - 1];
}

struct Data {
	int l, r;
} T[nmax * 4];

#define pli pair <ll, int>
pair < ll, int > st[nmax * 4];
void build(int id, int l, int r) {
	T[id] = {l, r};
	if (l == r) return;
	int mid = (l + r) / 2;
	build(lps(id), l, mid);
	build(rps(id), mid + 1, r);
}

pli comb(pli &A, pli &B) {
	return PAIR(A.fi + B.fi, A.se + B.se);
}

void upd(int id, int p) {
	auto &l = T[id].l;
	auto &r = T[id].r;
	if (l > abs(p) || r < abs(p)) return;
	if (l == r) {
		int sign = p > 0 ? 1 : -1;
		p = abs(p);
		st[id].fi += real_val(p) * sign;
		st[id].se += sign;
		return;
	}
	upd(lps(id), p);
	upd(rps(id), p);
	st[id] = comb(st[lps(id)], st[rps(id)]);
}

int wot(int id, ll S) {
	if (S == 0) return 0;
	auto &l = T[id].l;
	auto &r = T[id].r;
	if (l == r) {
		return min <ll> (S / real_val(l), st[id].se);
	}
	if (st[lps(id)].fi < S) {
		return st[lps(id)].se + wot(rps(id), S - st[lps(id)].fi);
	}
	else {
		return wot(lps(id), S);
	}
}

bool vis[nmax * 2];


void add(int i) {
	int u = tour[i];
	if (vis[u] == 0) {
		repv (val, List[u]) {
			upd(1, val);
		}
	}
	else {
		repv (val, List[u]) {
			upd(1, - val);
		}
	}
	vis[u] ^= 1;
}

void tintingyn()
{

	cin >> n >> m >> Q;

	rep (i, 1, n - 1) {
		int u, v;
		cin >> u >> v;
		ed[i] = {u, v};
		G[u].push_back(v);
		G[v].push_back(u);
	}

	dfs(1, 0);
	lca.build_lca();

	rep (i, 1, m) {
		cin >> b[i];
		int u, v;
		tie(u, v, ignore) = TUP(ed[b[i]][0], ed[b[i]][1], 0);
		if (dep[u] < dep[v]) swap(u, v);
		cin >> a[u];
		zi.push_back(a[u]);
		debug(u, v, a[u]);
		c[u].fi += a[u];
		c[u].se ++;
		List[u].push_back(a[u]);
	}

	sort(all(zi));
	special(zi);
	Lim = ssize(zi);

	rep (i, 1, n) {
		repv (v, List[i]) {
			v = Lower(all(zi), v) - zi.begin() + 1;
		}
		if (ssize(List[i])) {
			debug(i, List[i]);
		}
	}

	build(1, 1, Lim);

	dfs2(1, 0);

//	rep (i, 1, timer) {
//		cerr << i << sp << tour[i] << nl;
//	}

	rep (i, 0, Q - 1) {
		int u, v;
		ll x, y;
		cin >> u >> v >> x >> y;
		if (dep[u] > dep[v]) swap(u, v);
		if (ein[u] > ein[v]) swap(u, v);
		qs[i] = {u, v, x, y};
		int type = 2;
		int anc = lca.get_lca(u, v);
		if (anc == u) type = 1;
		query[i] = {type == 1 ? ein[u] : eout[u], ein[v], anc, type, i};
	}

	sort(query, query + Q);

	int L = 1;
	int R = L - 1;

	vector <int> ans(Q + 2, -1);

	rep (_i, 0, Q - 1) {
		auto &tv = query[_i];
		int l = tv.l;
		int r = tv.r;
		int anc = tv.anc;
		int type = tv.type;
		int id = tv.id;
		while (L > l) add(--L);
		while (R < r) add(++R);
		while (L < l) add(L++);
		while (R > r) add(R--);

		if (type == 1) add(l);

		if (id == 0) {
			rep (i, 1, timer) {
				if (vis[i] == 1) {
					cerr << tour[i] << sp;
				}
			}
			EL

				rep (i, l, r) {
					cerr << tour[i] << sp;
				}
				debug(tour[l], tour[r]);
				EL


			EL
		}

		auto S = qs[id][3];
		int res = wot(1, S);
		int sum = pf[tour[l]] + pf[tour[r]] - pf[anc] * 2;

		if (id == 0) {
			debug(S, res, st[1].fi, st[1].se, tour[l], tour[r]);
		}

		if (sum - res > qs[id][2]) {
			ans[id] = -1;
		}
		else {
			ans[id] = qs[id][2] - (sum - res);
		}

		if (type == 1) add(l);
	}

	rep (i, 0, Q - 1) {
		cout << ans[i] << nl;
	}

}

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

    //________________________________________________________________

    #define TASK "1"
    if(fopen(TASK".inp", "r"))
    { freopen(TASK".inp", "r", stdin); freopen(TASK".out", "w", stdout); }

    //________________________________________________________________

    //  CODE FROM HERE ...!





    int num_test = 1;
    // cin >> num_test;

    while(num_test--) {

        tintingyn();

    }


    cerr << '\n' << "Time elapsed: " << (1.0 * clock() / CLOCKS_PER_SEC) << " s\n" << nl;

    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

currencies.cpp: In function 'int main()':
currencies.cpp:426:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  426 |     { freopen(TASK".inp", "r", stdin); freopen(TASK".out", "w", stdout); }
      |       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
currencies.cpp:426:47: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  426 |     { freopen(TASK".inp", "r", stdin); freopen(TASK".out", "w", stdout); }
      |                                        ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...