Submission #650060

#TimeUsernameProblemLanguageResultExecution timeMemory
650060AlexandruabcdeFinancial Report (JOI21_financial)C++14
100 / 100
641 ms46648 KiB
#include <bits/stdc++.h> using namespace std; constexpr int NMAX = 3e5 + 5; constexpr int INF = 1e6; class SegmentTree { private: vector <int> arb; int Sz; void Update (int nod, int a, int b, int pos, int val) { if (a == b) { arb[nod] = val; return; } int mij = (a + b) / 2; if (pos <= mij) Update(2*nod, a, mij, pos, val); else Update(2*nod+1, mij+1, b, pos, val); arb[nod] = max(arb[2*nod], arb[2*nod+1]); } int Query (int nod, int a, int b, int qa, int qb) { if (qa <= a && b <= qb) return arb[nod]; int mij = (a + b) / 2; int ans_st = -1, ans_dr = -1; if (qa <= mij) ans_st = Query(2*nod, a, mij, qa, qb); if (mij < qb) ans_dr = Query(2*nod+1, mij+1, b, qa, qb); return max(ans_st, ans_dr); } public: void Init (int N) { Sz = N; arb.resize(4 * N + 5); for (int i = 0; i < arb.size(); ++ i ) arb[i] = -1; } void AddValue (int pos, int val) { Update(1, 1, Sz, pos, val); } int Ask (int st, int dr) { return Query(1, 1, Sz, st, dr); } }; class DSU { private: int Dad[NMAX]; int Sz[NMAX]; int Min[NMAX]; int N; int Reprezentant (int Node) { if (Dad[Node] == Node) return Node; Dad[Node] = Reprezentant(Dad[Node]); return Dad[Node]; } public: void Init (int n) { N = n; for (int i = 1; i <= N; ++ i ) { Sz[i] = 1; Dad[i] = i; Min[i] = i; } } void Unite (int x, int y) { x = Reprezentant(x); y = Reprezentant(y); if (x == y) return; if (Sz[x] <= Sz[y]) { Dad[x] = y; Sz[y] += Sz[x]; Min[y] = min(Min[y], Min[x]); } else { Dad[y] = x; Sz[x] += Sz[y]; Min[x] = min(Min[x], Min[y]); } } int Ask (int Node) { return Min[Reprezentant(Node)]; } }; DSU Pad; SegmentTree Sgt; int N, D; int A[NMAX]; int WhatBucket (int pos) { return (pos + D - 1) / D; } int Max[NMAX]; int Min[NMAX]; int dp[NMAX]; void Read () { ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> N >> D; for (int i = 1; i <= N; ++ i ) cin >> A[i]; } map <int, int> mp; int cnt = 0; void Normalize () { for (int i = 1; i <= N; ++ i ) mp[A[i]] = 1; for (auto &it : mp) it.second = ++cnt; for (int i = 1; i <= N; ++ i ) A[i] = mp[A[i]]; } vector <int> V[NMAX]; void Precompute () { Normalize(); for (int i = 0; i <= N+1; ++ i ) { Min[WhatBucket(i)] = INF; Max[WhatBucket(i)] = -INF; dp[i] = -1; } for (int i = 1; i <= N; ++ i ) V[A[i]].push_back(i); } void Solve () { Sgt.Init(N); Pad.Init(N); for (int i = 1; i <= N; ++ i ) { for (auto pos : V[i]) { dp[pos] = 1; int who_Buck = WhatBucket(pos); if (who_Buck > 1 && min(pos, Min[who_Buck]) <= Max[who_Buck-1] + D) -- who_Buck; int best = Pad.Ask(who_Buck); if (Min[best] <= pos) dp[pos] = Sgt.Ask(min(pos, Min[best]), pos) + 1; } for (auto pos : V[i]) { Min[WhatBucket(pos)] = min(Min[WhatBucket(pos)], pos); Max[WhatBucket(pos)] = max(Max[WhatBucket(pos)], pos); int buck = WhatBucket(pos); if (buck > 1 && Min[buck] <= Max[buck-1] + D) Pad.Unite(buck-1, buck); if (buck < WhatBucket(N) && Max[buck] + D >= Min[buck+1]) Pad.Unite(buck, buck+1); Sgt.AddValue(pos, dp[pos]); } } cout << Sgt.Ask(1, N) << '\n'; } int main () { Read(); Precompute(); Solve(); return 0; }

Compilation message (stderr)

Main.cpp: In member function 'void SegmentTree::Init(int)':
Main.cpp:45:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   45 |         for (int i = 0; i < arb.size(); ++ i )
      |                         ~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...