제출 #1036596

#제출 시각아이디문제언어결과실행 시간메모리
10365960npataTwo Currencies (JOI23_currencies)C++17
38 / 100
2154 ms1048576 KiB
#include<bits/stdc++.h> using namespace std; #define int long long #define vec vector const int N = 1<<17; const int CMX = (int)1<<31; struct Node { int cnt = 0; int sum = 0; Node* left = nullptr; Node* right = nullptr; Node* get_right() { if(right == nullptr) { right = new Node{}; } return right; } Node* get_left() { if(left == nullptr) { left = new Node{}; } return left; } void insert(int val, int l = 0, int r = CMX) { cnt++; sum += val; if(l+1 == r) return; int m = (l+r)/2; if(val >= m) { get_right()->insert(val, m, r); } else { get_left()->insert(val, l, m); } } ~Node() { delete left; delete right; } }; Node roots[N*3]; void insert(int i, int val) { i += N; roots[i].insert(val); while(i > 1) { i /= 2; roots[i].insert(val); } } int tree_sz[N]; int ri[N]; int t = 0; int depth[N]; vec<int> tree[N]; int par[N]; void dfs1(int u = 0, int p = -1) { par[u] = p; tree_sz[u] = 1; for(int v : tree[u]) { if(v == p) continue; depth[v] = depth[u]+1; dfs1(v, u); tree_sz[u] += tree_sz[v]; } } int head[N]; void heavy_light(int u = 0, int p = -1) { ri[u] = t++; pair<int, int> mxch{-1, -1}; for(int v : tree[u]) { if(v == p) continue; if(tree_sz[v] > mxch.second) { mxch = {v, tree_sz[v]}; } } if(mxch.first == -1) return; head[mxch.first] = head[u]; heavy_light(mxch.first, u); for(int v : tree[u]) { if(v == p || v == mxch.first) { continue; } head[v] = v; heavy_light(v, u); } } void tree_range_indices(int l, int r, vec<int>& res, int i = 1, int tl = 0, int tr = N) { if(tl >= r || tr <= l) return; if(tl >= l && tr <= r) { res.push_back(i); return; } int tm = (tl + tr)/2; tree_range_indices(l, r, res, i*2, tl, tm); tree_range_indices(l, r, res, i*2+1, tm, tr); } vec<int> range_indices(int u, int v) { vec<int> res = {}; while(u != v) { if(head[u] == head[v]) { if(depth[u] > depth[v]) swap(u, v); tree_range_indices(ri[u]+1, ri[v]+1, res); break; } if(depth[head[u]] < depth[head[v]]) swap(u, v); if(head[u] == u) { tree_range_indices(ri[u], ri[u]+1, res); u = par[u]; } else { tree_range_indices(ri[head[u]]+1, ri[u]+1, res); u = head[u]; } //cerr << "STUCK 2" << '\n'; } return res; } int32_t main() { ios_base::sync_with_stdio(false); cin.tie(0); int n, m, q; cin >> n >> m >> q; map<int, pair<int, int>> edges; for(int i = 0; i<n-1; i++) { int u, v; cin >> u >> v; u--;v--; tree[u].push_back(v); tree[v].push_back(u); edges.insert({i, {u, v}}); } dfs1(); heavy_light(); for(int i = 0; i<m; i++) { int ei, c; cin >> ei >> c; ei--; auto [u, v] = edges[ei]; if(depth[u] > depth[v]) swap(u, v); insert(ri[v], c); } for(int i = 0; i<q; i++) { int u, v, s, g; cin >> u >> v >> g >> s; u--; v--; vec<int> root_inds = range_indices(u, v); vec<Node*> nodes(root_inds.size()); int tot_cnt = 0; for(int i = 0; i<root_inds.size(); i++) { nodes[i] = &roots[root_inds[i]]; tot_cnt += nodes[i]->cnt; } int sum = 0; int cnt = 0; int l = 0; int r = CMX; while(l+1 != r) { int m = (l+r)/2; int cand_sum = sum; int cand_cnt = cnt; for(int i = 0; i<nodes.size(); i++) { cand_sum += nodes[i]->get_left()->sum; cand_cnt += nodes[i]->get_left()->cnt; } if(cand_sum <= s) { l = m; sum = cand_sum; cnt = cand_cnt; for(int i = 0; i<nodes.size(); i++) { nodes[i] = nodes[i]->get_right(); } } else { r = m; for(int i = 0; i<nodes.size(); i++) { nodes[i] = nodes[i]->get_left(); } } //cerr << "STUCK 1" << '\n'; } int cur_cnt = 0; for(int i = 0; i<nodes.size(); i++) { cur_cnt += nodes[i]->cnt; } //cerr << "CURCNT: " << cur_cnt << '\n'; cnt += min((s-sum)/l, cur_cnt); //cerr << tot_cnt << ' ' << cnt << ' ' << g << '\n'; assert(sum <= s); if(g < tot_cnt-cnt) cout << -1 << endl; else cout << g-(tot_cnt-cnt) << endl; } }

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

currencies.cpp: In function 'int32_t main()':
currencies.cpp:174:19: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  174 |   for(int i = 0; i<root_inds.size(); i++) {
      |                  ~^~~~~~~~~~~~~~~~~
currencies.cpp:186:20: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<Node*>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  186 |    for(int i = 0; i<nodes.size(); i++) {
      |                   ~^~~~~~~~~~~~~
currencies.cpp:194:21: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<Node*>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  194 |     for(int i = 0; i<nodes.size(); i++) {
      |                    ~^~~~~~~~~~~~~
currencies.cpp:200:21: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<Node*>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  200 |     for(int i = 0; i<nodes.size(); i++) {
      |                    ~^~~~~~~~~~~~~
currencies.cpp:209:19: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<Node*>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  209 |   for(int i = 0; i<nodes.size(); i++) {
      |                  ~^~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...