# |
제출 시각 |
아이디 |
문제 |
언어 |
결과 |
실행 시간 |
메모리 |
799899 |
2023-08-01T07:52:42 Z |
박상훈(#10082) |
수확 (JOI20_harvest) |
C++17 |
|
5000 ms |
16060 KB |
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
constexpr int MAXN = 200200;
int n, m, q, cnti, cntj;
ll L, c;
ll a[MAXN], b[MAXN];
vector<int> adj[MAXN], buf[MAXN];
int go[MAXN], f[MAXN], tmpf[MAXN], top[MAXN], visited[MAXN], inj[MAXN], outj[MAXN], comp[MAXN], typ[MAXN], ord[MAXN];
ll W[MAXN], s[MAXN], tmps[MAXN], g[MAXN], ofs[MAXN], ans[MAXN], T[MAXN], dp[MAXN];
struct Query{
int v;
ll t;
int i;
Query(){}
Query(int _v, ll _t, int _i): v(_v), t(_t), i(_i) {}
}Q[MAXN];
inline ll mydiv(ll x, ll y){
ll ret = x / y;
if (ret*y > x) return ret-1;
return ret;
}
inline ll mymod(ll x, ll y){
ll ret = x % y;
if (ret < 0) return ret + y;
return ret;
}
void dfs(int s, int root, int root2, int pa){
visited[s] = 2;
comp[s] = root;
if (pa > 0) dp[s] = dp[pa] + W[s];
else dp[s] = 0;
inj[s] = cntj;
for (auto &j:buf[s]){
f[cntj] = tmpf[j];
::s[cntj] = tmps[j];
top[cntj] = root2;
g[cntj] = -::s[cntj]-dp[f[cntj]]+ofs[root2];
g[cntj] = -g[cntj];
// printf(" j = %lld (cntj = %lld) -> s = %lld / cyc = %lld / g = %lld\n", j, cntj, ::s[cntj], ::s[cntj]+dp[f[cntj]], g[cntj]);
cntj++;
}
for (auto &v:adj[s]) dfs(v, root, root2, s);
outj[s] = cntj-1;
}
void init(){
cnti = cntj = 1;
// init go, W, adj
for (int i=1;i<=n;i++){
ll nc = c % L, quo = c / L;
if (a[i]-a[1] < nc){
go[i] = upper_bound(a+i+1, a+n+1, L+a[i]-nc) - a - 1;
W[i] = quo * L + L - (a[go[i]] - a[i]);
}
else{
go[i] = upper_bound(a+1, a+i+1, a[i]-nc) - a - 1;
W[i] = quo * L + a[i] - a[go[i]];
}
adj[go[i]].push_back(i);
}
// debug
// printf(" ok1\n");
// printf("go: ");
// for (int i=1;i<=n;i++) printf("%lld ", go[i]);
// printf("\n");
// printf("W: ");
// for (int i=1;i<=n;i++) printf("%lld ", W[i]);
// printf("\n");
// push j
for (int j=1;j<=m;j++){
tmpf[j] = upper_bound(a+1, a+n+1, b[j]) - a - 1;
if (tmpf[j]==0){
tmpf[j] = n;
tmps[j] = L - (a[n] - b[j]);
}
else{
tmps[j] = b[j] - a[tmpf[j]];
}
buf[tmpf[j]].push_back(j);
}
// printf(" ok2\n");
// get component info
for (int i=1;i<=n;i++) if (!visited[i]){
int root = -1;
for (int s=i;;s=go[s]){
if (visited[s]==1){root = s; break;}
visited[s] = 1;
}
assert(root!=-1);
ofs[root] = 0;
for (int s=root;;s=go[s]){
ord[s] = cnti++;
typ[s] = 1;
auto iter = find(adj[go[s]].begin(), adj[go[s]].end(), s);
assert(iter!=adj[go[s]].end());
adj[go[s]].erase(iter);
if (go[s]==root){
T[root] = ofs[s] + W[s];
break;
}
ofs[go[s]] = ofs[s] + W[s];
}
inj[root] = cntj;
for (int s=root;;s=go[s]){
dfs(s, root, s, 0);
if (go[s]==root) break;
}
outj[root] = cntj-1;
}
// printf("comp: ");
// for (int i=1;i<=n;i++) printf("%lld ", comp[i]);
// printf("\n");
// printf("typ: ");
// for (int i=1;i<=n;i++) printf("%lld ", typ[i]);
// printf("\n");
// printf("in/out: ");
// for (int i=1;i<=n;i++) printf("(%lld, %lld) ", inj[i], outj[i]);
// printf("\n");
}
void naive(){
for (int _=1;_<=q;_++){
auto [v, t, i] = Q[_];
ll ret = 0;
if (typ[v]==0){ // tree
// printf(" query %lld: tree\n", i);
for (int j=inj[v];j<=outj[v];j++){
if (t + dp[v] >= s[j] - dp[f[j]]) ret++;
}
}
else{ // cycle
// printf(" query %lld: cycle\n", i);
int idx = comp[v];
for (int j=inj[idx];j<=outj[idx];j++) if (t-ofs[v] >= g[j]){
// ret++;
// ret += mydiv((t-ofs[v]), T[idx]) - mydiv(g[j], T[idx]) - (mymod((t-ofs[v]), T[idx]) < mymod(g[j], T[idx]));
ret += (t-ofs[v]-g[j]) / T[idx] + 1;
// printf("ok ret = %lld\n", ret);
if (ord[v] < ord[top[j]]) ret--;
// printf("ok ret = %lld\n\n", ret);
}
}
ans[i] = ret;
}
}
signed main(){
scanf("%lld %lld %lld %lld", &n, &m, &L, &c);
for (int i=1;i<=n;i++) scanf("%lld", a+i);
for (int i=1;i<=m;i++) scanf("%lld", b+i);
scanf("%lld", &q);
for (int i=1;i<=q;i++){
scanf("%lld %lld", &Q[i].v, &Q[i].t);
Q[i].i = i;
}
init();
naive();
for (int i=1;i<=q;i++) printf("%lld\n", ans[i]);
}
Compilation message
harvest.cpp: In function 'int main()':
harvest.cpp:204:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
204 | scanf("%lld %lld %lld %lld", &n, &m, &L, &c);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
harvest.cpp:205:30: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
205 | for (int i=1;i<=n;i++) scanf("%lld", a+i);
| ~~~~~^~~~~~~~~~~~~
harvest.cpp:206:30: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
206 | for (int i=1;i<=m;i++) scanf("%lld", b+i);
| ~~~~~^~~~~~~~~~~~~
harvest.cpp:208:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
208 | scanf("%lld", &q);
| ~~~~~^~~~~~~~~~~~
harvest.cpp:210:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
210 | scanf("%lld %lld", &Q[i].v, &Q[i].t);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
6 ms |
9940 KB |
Output is correct |
2 |
Correct |
7 ms |
10452 KB |
Output is correct |
3 |
Correct |
85 ms |
10528 KB |
Output is correct |
4 |
Incorrect |
6 ms |
10452 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
5054 ms |
16060 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
6 ms |
9940 KB |
Output is correct |
2 |
Correct |
7 ms |
10452 KB |
Output is correct |
3 |
Correct |
85 ms |
10528 KB |
Output is correct |
4 |
Incorrect |
6 ms |
10452 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |