# |
제출 시각 |
아이디 |
문제 |
언어 |
결과 |
실행 시간 |
메모리 |
799943 |
2023-08-01T08:40:34 Z |
박상훈(#10082) |
수확 (JOI20_harvest) |
C++17 |
|
495 ms |
139072 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], visited[MAXN], inj[MAXN], outj[MAXN], comp[MAXN], typ[MAXN], ord[MAXN];
ll W[MAXN], ofs[MAXN], T[MAXN], dp[MAXN];
int f[MAXN], tmpf[MAXN], top[MAXN];
ll s[MAXN], tmps[MAXN], g[MAXN];
ll ans[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 / f = %lld / cyc = %lld / g = %lld\n", j, cntj, ::s[cntj], f[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(){
// init
for (int i=1;i<=n;i++){
adj[i].clear();
buf[i].clear();
}
fill(visited+1, visited+n+1, 0);
fill(typ+1, typ+n+1, 0);
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;
}
}
struct Seg{
vector<ll> X, tree;
int sz;
void push(ll x){
if (sz > 0){
sz = 0;
X.clear();
tree.clear();
}
X.push_back(x);
}
void init(){
sort(X.begin(), X.end());
X.erase(unique(X.begin(), X.end()), X.end());
sz = X.size();
tree.clear();
tree.resize(sz*2, 0);
}
void update(int p, ll x){
p = lower_bound(X.begin(), X.end(), p) - X.begin();
p += sz;
tree[p] += x;
for (p>>=1;p;p>>=1) tree[p] = tree[p<<1] + tree[p<<1|1];
}
ll query(ll l, ll r){
if (r==-1) r = sz;
else r = lower_bound(X.begin(), X.end(), r) - X.begin() + 1;
l = lower_bound(X.begin(), X.end(), l) - X.begin();
ll ret = 0;
for (l+=sz,r+=sz;l<r;l>>=1,r>>=1){
if (l&1) ret += tree[l++];
if (r&1) ret += tree[--r];
}
return ret;
}
}treeT1, treeC3[MAXN], treeC4[MAXN];
vector<array<ll, 3>> EC[MAXN];
void solve(){
vector<array<ll, 3>> ET;
for (int _=1;_<=q;_++){
auto [v, t, i] = Q[_];
if (typ[v]==0){
ET.push_back({t+dp[v], 1, _});
treeT1.push(inj[v]);
treeT1.push(outj[v]);
}
else{
EC[comp[v]].push_back({t-ofs[v], 1, _});
treeC3[comp[v]].push(mymod((t-ofs[v]), T[comp[v]])+1);
treeC4[comp[v]].push(ord[v]+1);
}
}
for (int j=1;j<=m;j++){
ET.push_back({s[j] + dp[f[j]], 0, j});
treeT1.push(j);
EC[comp[f[j]]].push_back({g[j], 0, j});
treeC3[comp[f[j]]].push(mymod(g[j], T[comp[f[j]]]));
treeC4[comp[f[j]]].push(ord[top[j]]);
}
sort(ET.begin(), ET.end());
treeT1.init();
for (auto &[val, typ, idx]:ET){
if (typ==0) treeT1.update(idx, 1);
else{
auto [v, t, i] = Q[idx];
ans[i] = treeT1.query(inj[v], outj[v]);
}
}
for (int idx=1;idx<=n;idx++){
sort(EC[idx].begin(), EC[idx].end());
treeC3[idx].init();
treeC4[idx].init();
ll cnt = 0, C2 = 0;
for (auto &[v, typ, ii]:EC[idx]){
if (typ==0){
int j = ii;
cnt++;
C2 += mydiv(g[j], T[idx]);
treeC3[idx].update(mymod(g[j], T[idx]), 1);
treeC4[idx].update(ord[top[j]], 1);
}
else{
auto [v, t, i] = Q[ii];
ans[i] = cnt + cnt * mydiv((t-ofs[v]), T[idx]) - C2 - treeC3[idx].query(mymod((t-ofs[v]), T[idx])+1, -1);
ans[i] -= treeC4[idx].query(ord[v]+1, -1);
}
}
}
}
ll naive2(){
vector<int> tim(m+1, 0);
vector<int> A(n+1);
for (int i=1;i<=n;i++) A[i] = a[i];
ll ret = 0;
for (int z=1;z<=Q[1].t;z++){
for (int i=1;i<=n;i++){
A[i]++;
if (A[i] >= L) A[i] = 0;
for (int j=1;j<=m;j++) if (A[i]==b[j] && tim[j]==0){
if (i==Q[1].v) ret++;
tim[j] = c;
}
}
for (int j=1;j<=m;j++) tim[j] = max(0LL, tim[j]-1);
}
return ret;
}
mt19937 seed(1557);
uniform_int_distribution<int> rng(0, 2147483647);
int getrand(int l, int r){return rng(seed)%(r-l+1) + l;}
void gen(){
n = getrand(1, 5);
m = getrand(1, 5);
L = getrand(n+m, 20);
c = getrand(1, 10);
set<int> V;
while((int)V.size() < n+m) V.insert(getrand(0, L-1));
vector<int> V2;
for (auto &x:V) V2.push_back(x);
shuffle(V2.begin(), V2.end(), seed);
for (int i=1;i<=n;i++) a[i] = V2[i-1];
for (int j=1;j<=m;j++) b[j] = V2[j+n-1];
sort(a+1, a+n+1);
sort(b+1, b+m+1);
// printf("fuck %lld\n", b[m]);
q = 1;
Q[1].v = getrand(1, n);
Q[1].t = getrand(1, 20);
Q[1].i = 1;
}
void stress(int tc){
printf("----------------------------\n");
printf("Stress #%lld\n", tc);
gen();
printf("Input:\n");
printf("%lld %lld %lld %lld\n", n, m, L, c);
for (int i=1;i<=n;i++) printf("%lld ", a[i]);
printf("\n");
for (int i=1;i<=m;i++) printf("%lld ", b[i]);
printf("\n");
printf("1\n");
printf("%lld %lld\n", Q[1].v, Q[1].t);
ll ans = naive2();
init();
naive();
ll out = ::ans[1];
printf("Answer: %lld\n", ans);
printf("Output: %lld\n", out);
assert(ans==out);
}
signed main(){
// for (int i=1;;i++) stress(i);
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();
solve();
for (int i=1;i<=q;i++) printf("%lld\n", ans[i]);
}
Compilation message
harvest.cpp: In function 'int main()':
harvest.cpp:412:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
412 | scanf("%lld %lld %lld %lld", &n, &m, &L, &c);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
harvest.cpp:413:30: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
413 | for (int i=1;i<=n;i++) scanf("%lld", a+i);
| ~~~~~^~~~~~~~~~~~~
harvest.cpp:414:30: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
414 | for (int i=1;i<=m;i++) scanf("%lld", b+i);
| ~~~~~^~~~~~~~~~~~~
harvest.cpp:416:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
416 | scanf("%lld", &q);
| ~~~~~^~~~~~~~~~~~
harvest.cpp:418:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
418 | scanf("%lld %lld", &Q[i].v, &Q[i].t);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
21 ms |
36824 KB |
Output is correct |
2 |
Correct |
22 ms |
37972 KB |
Output is correct |
3 |
Correct |
20 ms |
37788 KB |
Output is correct |
4 |
Correct |
25 ms |
37684 KB |
Output is correct |
5 |
Correct |
21 ms |
37916 KB |
Output is correct |
6 |
Correct |
25 ms |
37952 KB |
Output is correct |
7 |
Correct |
20 ms |
37972 KB |
Output is correct |
8 |
Correct |
21 ms |
37636 KB |
Output is correct |
9 |
Correct |
19 ms |
37576 KB |
Output is correct |
10 |
Correct |
20 ms |
37648 KB |
Output is correct |
11 |
Correct |
22 ms |
37640 KB |
Output is correct |
12 |
Correct |
22 ms |
37716 KB |
Output is correct |
13 |
Correct |
23 ms |
37836 KB |
Output is correct |
14 |
Correct |
22 ms |
37852 KB |
Output is correct |
15 |
Correct |
27 ms |
37844 KB |
Output is correct |
16 |
Correct |
21 ms |
37776 KB |
Output is correct |
17 |
Correct |
22 ms |
37804 KB |
Output is correct |
18 |
Correct |
21 ms |
37788 KB |
Output is correct |
19 |
Correct |
21 ms |
37800 KB |
Output is correct |
20 |
Correct |
20 ms |
37696 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
189 ms |
58020 KB |
Output is correct |
2 |
Correct |
222 ms |
73732 KB |
Output is correct |
3 |
Correct |
301 ms |
96952 KB |
Output is correct |
4 |
Correct |
237 ms |
88600 KB |
Output is correct |
5 |
Correct |
204 ms |
94300 KB |
Output is correct |
6 |
Correct |
199 ms |
94312 KB |
Output is correct |
7 |
Correct |
191 ms |
72436 KB |
Output is correct |
8 |
Correct |
195 ms |
72432 KB |
Output is correct |
9 |
Correct |
367 ms |
88164 KB |
Output is correct |
10 |
Correct |
221 ms |
87088 KB |
Output is correct |
11 |
Correct |
391 ms |
87108 KB |
Output is correct |
12 |
Correct |
356 ms |
87176 KB |
Output is correct |
13 |
Correct |
400 ms |
87004 KB |
Output is correct |
14 |
Correct |
246 ms |
85676 KB |
Output is correct |
15 |
Correct |
318 ms |
86740 KB |
Output is correct |
16 |
Correct |
202 ms |
87728 KB |
Output is correct |
17 |
Correct |
173 ms |
87768 KB |
Output is correct |
18 |
Correct |
150 ms |
63344 KB |
Output is correct |
19 |
Correct |
136 ms |
63348 KB |
Output is correct |
20 |
Correct |
171 ms |
79004 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
21 ms |
36824 KB |
Output is correct |
2 |
Correct |
22 ms |
37972 KB |
Output is correct |
3 |
Correct |
20 ms |
37788 KB |
Output is correct |
4 |
Correct |
25 ms |
37684 KB |
Output is correct |
5 |
Correct |
21 ms |
37916 KB |
Output is correct |
6 |
Correct |
25 ms |
37952 KB |
Output is correct |
7 |
Correct |
20 ms |
37972 KB |
Output is correct |
8 |
Correct |
21 ms |
37636 KB |
Output is correct |
9 |
Correct |
19 ms |
37576 KB |
Output is correct |
10 |
Correct |
20 ms |
37648 KB |
Output is correct |
11 |
Correct |
22 ms |
37640 KB |
Output is correct |
12 |
Correct |
22 ms |
37716 KB |
Output is correct |
13 |
Correct |
23 ms |
37836 KB |
Output is correct |
14 |
Correct |
22 ms |
37852 KB |
Output is correct |
15 |
Correct |
27 ms |
37844 KB |
Output is correct |
16 |
Correct |
21 ms |
37776 KB |
Output is correct |
17 |
Correct |
22 ms |
37804 KB |
Output is correct |
18 |
Correct |
21 ms |
37788 KB |
Output is correct |
19 |
Correct |
21 ms |
37800 KB |
Output is correct |
20 |
Correct |
20 ms |
37696 KB |
Output is correct |
21 |
Correct |
189 ms |
58020 KB |
Output is correct |
22 |
Correct |
222 ms |
73732 KB |
Output is correct |
23 |
Correct |
301 ms |
96952 KB |
Output is correct |
24 |
Correct |
237 ms |
88600 KB |
Output is correct |
25 |
Correct |
204 ms |
94300 KB |
Output is correct |
26 |
Correct |
199 ms |
94312 KB |
Output is correct |
27 |
Correct |
191 ms |
72436 KB |
Output is correct |
28 |
Correct |
195 ms |
72432 KB |
Output is correct |
29 |
Correct |
367 ms |
88164 KB |
Output is correct |
30 |
Correct |
221 ms |
87088 KB |
Output is correct |
31 |
Correct |
391 ms |
87108 KB |
Output is correct |
32 |
Correct |
356 ms |
87176 KB |
Output is correct |
33 |
Correct |
400 ms |
87004 KB |
Output is correct |
34 |
Correct |
246 ms |
85676 KB |
Output is correct |
35 |
Correct |
318 ms |
86740 KB |
Output is correct |
36 |
Correct |
202 ms |
87728 KB |
Output is correct |
37 |
Correct |
173 ms |
87768 KB |
Output is correct |
38 |
Correct |
150 ms |
63344 KB |
Output is correct |
39 |
Correct |
136 ms |
63348 KB |
Output is correct |
40 |
Correct |
171 ms |
79004 KB |
Output is correct |
41 |
Correct |
389 ms |
117076 KB |
Output is correct |
42 |
Correct |
482 ms |
139072 KB |
Output is correct |
43 |
Correct |
195 ms |
88272 KB |
Output is correct |
44 |
Correct |
288 ms |
123272 KB |
Output is correct |
45 |
Correct |
332 ms |
134840 KB |
Output is correct |
46 |
Correct |
311 ms |
135608 KB |
Output is correct |
47 |
Correct |
320 ms |
136364 KB |
Output is correct |
48 |
Correct |
310 ms |
135172 KB |
Output is correct |
49 |
Correct |
306 ms |
134808 KB |
Output is correct |
50 |
Correct |
338 ms |
112036 KB |
Output is correct |
51 |
Correct |
309 ms |
111252 KB |
Output is correct |
52 |
Correct |
450 ms |
126792 KB |
Output is correct |
53 |
Correct |
495 ms |
123500 KB |
Output is correct |
54 |
Correct |
470 ms |
126780 KB |
Output is correct |
55 |
Correct |
452 ms |
125896 KB |
Output is correct |
56 |
Correct |
363 ms |
125548 KB |
Output is correct |
57 |
Correct |
339 ms |
126352 KB |
Output is correct |
58 |
Correct |
358 ms |
127096 KB |
Output is correct |
59 |
Correct |
305 ms |
124728 KB |
Output is correct |
60 |
Correct |
296 ms |
125248 KB |
Output is correct |
61 |
Correct |
306 ms |
125220 KB |
Output is correct |
62 |
Correct |
489 ms |
126400 KB |
Output is correct |
63 |
Correct |
263 ms |
99488 KB |
Output is correct |
64 |
Correct |
257 ms |
99572 KB |
Output is correct |
65 |
Correct |
313 ms |
99776 KB |
Output is correct |
66 |
Correct |
243 ms |
100560 KB |
Output is correct |
67 |
Correct |
253 ms |
100016 KB |
Output is correct |
68 |
Correct |
259 ms |
100968 KB |
Output is correct |
69 |
Correct |
365 ms |
118544 KB |
Output is correct |
70 |
Correct |
351 ms |
115032 KB |
Output is correct |
71 |
Correct |
345 ms |
116368 KB |
Output is correct |
72 |
Correct |
352 ms |
116612 KB |
Output is correct |