Submission #212290

#TimeUsernameProblemLanguageResultExecution timeMemory
212290ksun48Harvest (JOI20_harvest)C++14
100 / 100
897 ms132656 KiB
#include <bits/stdc++.h> #include <bits/extc++.h> /** keep-include */ using namespace std; namespace std { template<class Fun> class y_combinator_result { Fun fun_; public: template<class T> explicit y_combinator_result(T &&fun): fun_(std::forward<T>(fun)) {} template<class ...Args> decltype(auto) operator()(Args &&...args) { return fun_(std::ref(*this), std::forward<Args>(args)...); } }; template<class Fun> decltype(auto) y_combinator(Fun &&fun) { return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun)); } } // namespace std using namespace __gnu_pbds; template<class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; using ll = long long; int main(){ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); ll n, m, l, c; cin >> n >> m >> l >> c; vector<ll> next_vert(n); vector<ll> next_dist(n); vector<vector<ll> > when_add(n); { vector<ll> a(n); for(ll& x : a){ cin >> x; x = (l-1) - x; } reverse(a.begin(), a.end()); for(ll i = 0; i < n; i++){ ll res = (((a[i] + c) % l) + l) % l; auto r = lower_bound(a.begin(), a.end(), res); if(r == a.end()){ next_dist[i] = c + l + a.front() - res; next_vert[i] = 0; } else { next_dist[i] = c + *r - res; next_vert[i] = r - a.begin(); } } vector<ll> b(m); for(ll& x : b){ cin >> x; x = (l-1) - x; } for(ll x : b){ ll res = x; auto r = lower_bound(a.begin(), a.end(), res); ll d; ll v; if(r == a.end()){ d = l + a.front() - res; v = 0; } else { d = *r - res; v = r - a.begin(); } when_add[v].push_back(d); } } vector<bool> cycle_start(n, false); vector<vector<ll> > children(n); vector<ll> root_dist(n); { vector<ll> seen(n, 0); for(ll i = 0; i < n; i++){ ll cur = i; while(seen[cur] == 0){ seen[cur] = 1; cur = next_vert[cur]; } if(seen[cur] == 1){ cycle_start[cur] = true; } cur = i; while(seen[cur] == 1){ seen[cur] = 2; cur = next_vert[cur]; } } for(ll i = 0; i < n; i++){ if(!cycle_start[i]){ children[next_vert[i]].push_back(i); } } for(ll i = 0; i < n; i++){ if(!cycle_start[i]) continue; y_combinator([&](auto self, ll v, ll dist) -> void { root_dist[v] = dist; for(ll w : children[v]){ self(w, dist + next_dist[w]); } })(i, 0); } } vector<vector<ll> > queries_loc(n); ll q; cin >> q; vector<ll> qv(q); vector<ll> qt(q); vector<ll> answer(q, 0); for(ll i = 0; i < q; i++){ cin >> qv[i] >> qt[i]; qv[i]--; qv[i] = n-1-qv[i]; queries_loc[qv[i]].push_back(i); } // solve for tree first mt19937_64 mt(48); vector<Tree<pair<ll, unsigned long long> > > when(n); for(ll i = 0; i < n; i++){ if(!cycle_start[i]) continue; ll loc = y_combinator([&](auto self, ll v) -> ll { ll cur = v; for(ll t : when_add[v]){ when[v].insert({t + root_dist[v], mt()}); } for(ll w : children[v]){ ll g = self(w); if(when[cur].size() < when[g].size()) swap(cur, g); for(auto x : when[g]) when[cur].insert(x); when[g] = {}; } for(ll idx : queries_loc[v]){ answer[idx] += when[cur].order_of_key({qt[idx] + root_dist[v], -1}); } return cur; })(i); vector<pair<ll, ll> > queries; ll len = next_dist[i] + root_dist[next_vert[i]]; ll cur = i; while(true){ for(ll idx : queries_loc[cur]){ queries.push_back({qt[idx] - (len - root_dist[cur]), idx}); } cur = next_vert[cur]; if(cur == i) break; } for(auto x : when[loc]){ queries.push_back({x.first, -1}); } sort(queries.begin(), queries.end()); Tree<pair<ll, unsigned long long> > f; ll del = 0; for(pair<ll, ll> qq : queries){ if(qq.second == -1){ f.insert({qq.first % len, mt()}); del -= (qq.first / len); } else { answer[qq.second] += del + (qq.first / len) * (ll)(f.size()) + f.order_of_key({qq.first % len, -1}); } } } for(ll i = 0; i < q; i++){ cout << answer[i] << '\n'; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...