Submission #431657

#TimeUsernameProblemLanguageResultExecution timeMemory
431657oolimry수확 (JOI20_harvest)C++17
0 / 100
165 ms72600 KiB
#include <bits/stdc++.h> using namespace std; #define sz(x) (int) (x).size() #define all(x) (x).begin(), (x).end() #define show(x) cerr << #x << " is " << x << endl; #define show2(x,y) cerr << #x << " is " << x << " " << #y << " is " << y << endl; #define show3(x,y,z) cerr << #x << " is " << x << " " << #y << " is " << y << " " << #z << " is " << z << endl; #define tern(cond, a, b) (cond ? a : b) typedef long long lint; typedef pair<int,int> ii; lint n, m, L, T; const int BUFF = 250000; const int ROOT = 500000; vector<lint> person; lint apple[500005]; lint point[500005]; bool vis[500005]; lint getdis(int i){ lint dis = person[i%BUFF] - person[point[i%BUFF]%BUFF]; if(dis < T){ dis += (T/L)*L; } while(dis < T) dis += L; return dis; } lint inf = 1e18 + 1e17; map<lint,lint> infs; vector<ii> adj[500005]; lint cyclesz[500005]; lint dis[500005]; lint low[500005]; lint high[500005]; lint maxval[500005]; lint total[500005]; lint rep[500005]; vector<lint> stuff[500005]; lint toinf[500005]; lint sumreps[500005]; vector<lint> allreps; vector<lint> mods[500005]; lint ppcnt = 0; void dfs(lint u, int p = -1){ low[u] = high[u] = ppcnt++; for(ii e : adj[u]){ lint v = e.first, w = e.second; if(v == p) continue; dis[v] = dis[u] + w; if(u == ROOT){ rep[v] = v; allreps.push_back(v); } else rep[v] = rep[u]; dfs(v, u); high[u] = max(high[u], high[v]); } } void dfs2(lint u, int p = -1){ for(ii e : adj[u]){ lint v = e.first; if(v == p) continue; dfs2(v, u); maxval[u] = max(maxval[u], maxval[v]); total[u] += total[v]; } } const int N = (1<<19); vector<lint> tree[2*N]; inline void addshit(int u, lint t){ t += dis[u]; //show2(u, t); maxval[u] = max(maxval[u], t); stuff[rep[u]].push_back(t); total[u]++; for(int i = low[u] + N;i > 0;i >>= 1) tree[i].push_back(t); } inline void getready(){ for(int i = 0;i < 2*N;i++) sort(all(tree[i])); } inline lint get(vector<lint> &v, lint t){ return (lint)(upper_bound(all(v), t) - v.begin()); } inline lint query(int u, lint t){ lint res = 0; for(int l = low[u]+N, r = high[u]+N+1;l < r;l >>= 1, r >>= 1){ if(l&1) res += get(tree[l++], t); if(r&1) res += get(tree[--r], t); } return res; } int main(){ ios_base::sync_with_stdio(false); cin.tie(0); memset(point, -1, sizeof(point)); cin >> n >> m >> L >> T; person.resize(n); for(int i = 0;i < n;i++) cin >> person[i]; for(int i = 0;i < m;i++) cin >> apple[i]; for(int i = 0;i < n;i++){ auto it = upper_bound(all(person), person[i] - (T%L)); if(it == person.begin()) it = upper_bound(all(person), person[i] - (T%L) + L); it--; point[i] = it - person.begin(); point[i+BUFF] = point[i]+BUFF; } for(int i = 0;i < n;i++){ set<int> cur; int u = i; int cycle = -1; while(true){ if(cur.find(u) != cur.end()) cycle = u; cur.insert(u); if(vis[u]) break; vis[u] = true; u = point[u]; } if(cycle == -1) continue; lint totaldis = 0; u = cycle; vector<int> nodes; while(true){ nodes.push_back(u); totaldis += getdis(u); u = point[u]; if(u == cycle) break; } for(int x : nodes){ cyclesz[x] = totaldis; cyclesz[x+BUFF] = totaldis; } point[cycle] += BUFF; point[cycle+BUFF] = ROOT; } for(int i = 0;i <= ROOT;i++){ if(point[i] == -1) continue; if(point[i] == ROOT) adj[ROOT].push_back(ii(i, 0)); else{ lint dis = getdis(i); adj[point[i]].push_back(ii(i, dis)); } } dfs(ROOT); for(int i = 0;i < m;i++){ auto it = lower_bound(all(person), apple[i]); if(it == person.begin()) it = person.end(); it--; int x = it - person.begin(); lint t = apple[i] - person[x]; if(t < 0) t += L; addshit(x, t); } getready(); dfs2(ROOT); for(lint r : allreps){ //show(r); for(lint x : stuff[r]){ lint MM = cyclesz[r]; lint I = inf; I /= MM; I *= MM; I--; infs[MM] = I; lint hm = (I-x)/MM + 1; sumreps[r] += hm; //show(hm); mods[r].push_back(x%MM); } sort(all(mods[r])); } //show(inf); int Q; cin >> Q; while(Q--){ lint u, t; cin >> u >> t; u--; lint ans = 0; ans += query(u, t+dis[u]); if(cyclesz[u+BUFF] != 0){ t += dis[u+BUFF]; lint r = rep[u+BUFF]; ans += sumreps[r]; lint MM = cyclesz[r]; //show2(t, t%MM); lint fulls = (infs[MM]-(t+1))/MM; fulls *= sz(stuff[r]); if(fulls >= 0){ ans -= fulls; ans -= (sz(stuff[r]) - (upper_bound(all(mods[r]), t%MM) - mods[r].begin())); } } cout << ans << '\n'; } /* for(int i = 0;i <= ROOT;i++){ if(point[i] == -1 and i != ROOT) continue; show3(i, low[i], high[i]); } //*/ }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...