Submission #1328064

#TimeUsernameProblemLanguageResultExecution timeMemory
1328064vlomaczkHarvest (JOI20_harvest)C++20
0 / 100
1822 ms63768 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
using namespace __gnu_pbds;
using namespace std;
 
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

struct Query {
	ll v, t, i;
};

ll M = 200'010;
vector<vector<pair<ll, ll>>> g(M);
vector<vector<ll>> mine(M);
vector<pair<ll, ll>> nxt(M, {-1, 0}), cykl(M, {-1, 0});
vector<ll> depth(M), vis(M), ans(M), root(M), roots, P(M, 0), on_cycle(M), path;
vector<Query> queries(M);

void meduza_dfs(ll v) {
	path.push_back(v);
	vis[v] = 1;
	auto[u,d] = nxt[v];
	if(vis[u]==2) {
		root[v] = root[u];
		vis[v] = 2;
	} else if(vis[u]==1) {
		P[v] = depth[v] - depth[u] + d;
		root[v] = v;
		roots.push_back(v);
		
		ll idx = path.size()-1;
		while(path[idx] != u) {
			on_cycle[path[idx]] = 1;
			idx--;
		}
		on_cycle[u] = 1;

		cykl[v] = nxt[v];
		nxt[v].first = -1;
	} else {
		depth[u] = depth[v] + d;
		meduza_dfs(u);
		root[v] = root[u];
	}
	vis[v] = 2;
	path.pop_back();
}

ll base = 1<<19;
vector<ll> Tree(2*base); 

void update(ll x, ll val) {
	x += base;
	Tree[x] += val;
	x/=2;
	while(x > 0) {
		Tree[x] = Tree[x+x] + Tree[x+x+1];
		x/=2;
	}
}

ll query(ll a, ll b) {
	a+=base-1;
	b+=base+1;
	ll ans = 0;
	while(a/2 != b/2) {
		if(a%2==0) ans += Tree[a+1];
		if(b%2==1) ans += Tree[b-1];
		a/=2; b/=2;
	}
	return ans;
}

ll cnt = 1;
vector<ll> pre(M), post(M);

void pre_dfs(ll v) {
	pre[v] = cnt++;	
	for(auto[u,k] : g[v]) {
		depth[u] = depth[v] + k;
		pre_dfs(u);
	}
	post[v] = cnt++;
}

ll flor(ll a, ll b) {
	if(a >= 0) return a/b;
	return a/b - 1;
}

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> ludzie(n), jablka(m);
	for(ll i=0; i<n; ++i) cin >> ludzie[i];
	for(ll i=0; i<m; ++i) cin >> jablka[i];
	ll q; cin >> q;
	for(ll i=0; i<q; ++i) {
		ll v, t;
		cin >> v >> t;
		queries[i] = {v-1, t, i};
	}
	auto dist = [&](ll a, ll b) {
		if(a<=b) return b-a;
		else return L + b - a;
	};
	auto dist_emp = [&](ll x, ll y) {
		return dist(ludzie[x], ludzie[y]);
	};
	ll Pan = n-1;
	ll idx = 0;
	for(ll i=0; i<m; ++i) {
		while(idx < n && ludzie[idx] <= jablka[i]) {
			Pan = idx;
			idx++;
		}
		mine[Pan].push_back(dist(ludzie[Pan], jablka[i]));
	}
	for(ll i=0; i<n; ++i) sort(mine[i].begin(), mine[i].end());
	ll iterator = 0;
	ll cl = (C%L ? C%L : L);
	for(ll i=0; i<n; ++i) {
		while(dist_emp((iterator+1)%n, i) >= cl) iterator = (iterator+1)%n;
		ll D = dist_emp(iterator, i) + (dist_emp(iterator, i) < cl ? L : 0) + L*(C/L);
		nxt[i] = {iterator, D};
		// cout << i << " -> " << iterator << " " << D << "\n";
	}
	for(ll i=0; i<n; ++i) if(!vis[i]) meduza_dfs(i);
	for(ll i=0; i<n; ++i) if(nxt[i].first!=-1) g[nxt[i].first].push_back({i, nxt[i].second});
	for(auto r : roots) {
		depth[r] = 0;
		pre_dfs(r);
	}
	vector<vector<pair<ll, ll>>> zap1(n); // zap1[v][..] = {T, q_idx}
	vector<pair<ll, pair<ll, ll>>> zap2; // zap2[..] = {T + depth, {q_idx, v}}
	for(ll idx=0; idx<q; ++idx) {
		auto[v,t,i] = queries[idx];
		zap2.push_back({t + depth[v], {i, v}});
		if(on_cycle[v]) {
			if(t > P[root[v]]-depth[v]) zap1[root[v]].push_back({t-P[root[v]]+depth[v], i});
		}
	}
	for(ll i=0; i<n; ++i) {
		for(auto a : mine[i]) zap2.push_back({a + depth[i], {-1, i}}); 
	}
	/*for(ll i=0; i<n; ++i) cout << on_cycle[i] << " "; cout << "\n";
	for(ll i=0; i<n; ++i) cout << root[i] << " "; cout << "\n";
	for(ll i=0; i<n; ++i) cout << cykl[i].first << " "; cout << "\n";
	for(ll i=0; i<n; ++i) cout << depth[i] << " "; cout << "\n";*/

	sort(zap2.begin(), zap2.end());
	for(auto[T, stat] : zap2) {
		auto[q_idx, v] = stat;
		if(q_idx==-1) update(pre[v], 1);
		else ans[q_idx] += query(pre[v], post[v]);
	}
	vector<vector<ll>> child(n);
	for(ll i=0; i<n; ++i) {
		// cout << i << ": ";
		for(auto a : mine[i]) {
			child[root[i]].push_back(a + depth[i]);
			// cout << a << " ";
		}
		// cout << "\n";
	}
	for(auto r : roots) {
		sort(child[r].begin(), child[r].end());
		ll D = P[r];
		for(auto[T, q_idx] : zap1[r]) {
			// cout << T << " " << q_idx << "\n";
			ll res = 0;
			for(auto a : child[r]) {
				// cout << a << " - " << max(0LL, flor(T-a, D) + 1) << '\n';
				res += max(0LL, flor(T-a, D) + 1);
			}
			ans[q_idx] += res;
		} 
	}
 	for(ll i=0; i<q; ++i) cout << ans[i] << "\n";

	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...