# |
제출 시각 |
아이디 |
문제 |
언어 |
결과 |
실행 시간 |
메모리 |
799913 |
2023-08-01T08:18:42 Z |
박상훈(#10082) |
수확 (JOI20_harvest) |
C++17 |
|
5000 ms |
16004 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;
}
}
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();
naive();
for (int i=1;i<=q;i++) printf("%lld\n", ans[i]);
}
Compilation message
harvest.cpp: In function 'int main()':
harvest.cpp:299:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
299 | scanf("%lld %lld %lld %lld", &n, &m, &L, &c);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
harvest.cpp:300:30: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
300 | for (int i=1;i<=n;i++) scanf("%lld", a+i);
| ~~~~~^~~~~~~~~~~~~
harvest.cpp:301:30: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
301 | for (int i=1;i<=m;i++) scanf("%lld", b+i);
| ~~~~~^~~~~~~~~~~~~
harvest.cpp:303:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
303 | scanf("%lld", &q);
| ~~~~~^~~~~~~~~~~~
harvest.cpp:305:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
305 | 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 |
10532 KB |
Output is correct |
4 |
Correct |
6 ms |
10452 KB |
Output is correct |
5 |
Correct |
10 ms |
10760 KB |
Output is correct |
6 |
Correct |
12 ms |
10828 KB |
Output is correct |
7 |
Correct |
13 ms |
10864 KB |
Output is correct |
8 |
Correct |
7 ms |
10452 KB |
Output is correct |
9 |
Correct |
6 ms |
10420 KB |
Output is correct |
10 |
Correct |
6 ms |
10452 KB |
Output is correct |
11 |
Correct |
6 ms |
10508 KB |
Output is correct |
12 |
Correct |
29 ms |
10580 KB |
Output is correct |
13 |
Correct |
57 ms |
10628 KB |
Output is correct |
14 |
Correct |
40 ms |
10636 KB |
Output is correct |
15 |
Correct |
9 ms |
10708 KB |
Output is correct |
16 |
Correct |
9 ms |
10652 KB |
Output is correct |
17 |
Correct |
8 ms |
10632 KB |
Output is correct |
18 |
Correct |
9 ms |
10580 KB |
Output is correct |
19 |
Correct |
8 ms |
10580 KB |
Output is correct |
20 |
Correct |
8 ms |
10580 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
5061 ms |
16004 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 |
10532 KB |
Output is correct |
4 |
Correct |
6 ms |
10452 KB |
Output is correct |
5 |
Correct |
10 ms |
10760 KB |
Output is correct |
6 |
Correct |
12 ms |
10828 KB |
Output is correct |
7 |
Correct |
13 ms |
10864 KB |
Output is correct |
8 |
Correct |
7 ms |
10452 KB |
Output is correct |
9 |
Correct |
6 ms |
10420 KB |
Output is correct |
10 |
Correct |
6 ms |
10452 KB |
Output is correct |
11 |
Correct |
6 ms |
10508 KB |
Output is correct |
12 |
Correct |
29 ms |
10580 KB |
Output is correct |
13 |
Correct |
57 ms |
10628 KB |
Output is correct |
14 |
Correct |
40 ms |
10636 KB |
Output is correct |
15 |
Correct |
9 ms |
10708 KB |
Output is correct |
16 |
Correct |
9 ms |
10652 KB |
Output is correct |
17 |
Correct |
8 ms |
10632 KB |
Output is correct |
18 |
Correct |
9 ms |
10580 KB |
Output is correct |
19 |
Correct |
8 ms |
10580 KB |
Output is correct |
20 |
Correct |
8 ms |
10580 KB |
Output is correct |
21 |
Execution timed out |
5061 ms |
16004 KB |
Time limit exceeded |
22 |
Halted |
0 ms |
0 KB |
- |