이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
//#include <atcoder/maxflow.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
#include <iostream>
#include <map>
#include <list>
#include <set>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>
#include <queue>
#include <deque>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <iterator>
#include <random>
#include <chrono>
#include <complex>
#include <bitset>
#include <fstream>
#define forr(i,start,count) for (int i = (start); i < (start)+(count); ++i)
#define set_map_includes(set, elt) (set.find((elt)) != set.end())
#define readint(i) int i; cin >> i
#define readll(i) ll i; cin >> i
#define readdouble(i) double i; cin >> i
#define readstring(s) string s; cin >> s
typedef long long ll;
//using namespace __gnu_pbds;
//using namespace atcoder;
using namespace std;
const ll modd = (1000LL * 1000LL * 1000LL + 7LL);
//const ll modd = 998244353;
template<class T>
class SegmentTree2 {
public:
SegmentTree2(const vector<T>& data, function<T(T,T)> f_, T zero_value = 0) : zv(zero_value), f(f_) {
Initialize(data);
}
SegmentTree2(int n, function<T(T,T)> f_, T zero_value = 0) : zv(zero_value), f(f_) {
vector<T> temp(n, zv);
Initialize(temp);
}
T operator[](int i) {
return tree[B+i];
}
T GetEvaluation(int L, int R) { // "min/max" on interval [L,R); 0-based indexing, as usual
if (R<=L) { return zv; }
return GetEvaluationHelper(L, R, 0, B, 1);
}
void SetVal(int i, T val) {
tree[B+i] = val;
for(int j = (B + i) / 2; j >= 1; j /= 2) {
tree[j] = f(tree[2*j], tree[2*j+1]);
}
}
private:
vector<T> tree;
int B; // power of two greater than size of input data
T zv;
function<T(T,T)> f;
void Initialize(const vector<T>& data) {
B = 1;
while(B < data.size()) {B *= 2; }
tree = std::move(vector<T>(2*B, zv));
copy(data.begin(), data.end(), next(tree.begin(), B));
for(int i = B - 1; i >= 1; --i) {
tree[i] = f(tree[2*i], tree[2*i+1]);
}
}
T GetEvaluationHelper(int L, int R, int start, int length, int tree_index) {
if (L==R) { return zv; }
if ((L==start) && (R==start+length)) { return tree[tree_index]; }
int midpoint = start + length/2;
T left_ = zv, right_ = zv;
if (L<=min(midpoint,R)) {
left_ = GetEvaluationHelper(L, min(midpoint,R), start, length/2, 2*tree_index);
}
if (max(midpoint,L)<=R) {
right_ = GetEvaluationHelper(max(midpoint,L), R, midpoint, length/2, 2*tree_index+1);
}
return f(left_, right_);
}
};
class block {
public:
set<pair<int,int>> intervals;
map<int,set<int>> length_ordered;
int d;
int n;
block(int nn, int dd) : n(nn), d(dd) {}
void add(int i) {
auto it = intervals.lower_bound(make_pair(i,i));
bool merge_right = ((it!=intervals.end()) && (it->first==i+1));
bool merge_left = ((it!=intervals.begin()) && (prev(it)->second==i));
if ((!merge_left) && (!merge_right)) {
intervals.insert(make_pair(i, i+1));
length_ordered[1].insert(i);
}
if ((!merge_left) && (merge_right)) {
int r = it->second;
intervals.erase(it);
length_ordered[r-i-1].erase(i+1);
if (length_ordered[r-i-1].empty()) { length_ordered.erase(r-i-1); }
intervals.insert(make_pair(i, r));
length_ordered[r-i].insert(i);
}
if ((merge_left) && (!merge_right)) {
int l = prev(it)->first;
intervals.erase(prev(it));
length_ordered[i-l].erase(l);
if (length_ordered[i-l].empty()) { length_ordered.erase(i-l); }
intervals.insert(make_pair(l, i+1));
length_ordered[i+1-l].insert(l);
}
if ((merge_left) && (merge_right)) {
int l = prev(it)->first;
int r = it->second;
it = intervals.erase(it);
intervals.erase(prev(it));
length_ordered[r-i-1].erase(i+1);
if (length_ordered[r-i-1].empty()) { length_ordered.erase(r-i-1); }
length_ordered[i-l].erase(l);
if (length_ordered[i-l].empty()) { length_ordered.erase(i-l); }
intervals.insert(make_pair(l, r));
length_ordered[r-l].insert(l);
}
}
int upto(int i) {
auto it = length_ordered.lower_bound(d);
if (it==length_ordered.end()) { return n; }
auto it2 = it->second.lower_bound(i);
if (it2==it->second.end()) { return n; }
return *it2+d;
}
};
int main(int argc, char *argv[]) {
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
uniform_int_distribution<int> rand_gen(0, modd); // rand_gen(rng) gets the rand no
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.precision(12);
// readint(test_cases);
int test_cases = 1;
forr(t, 1, test_cases) {
readint(n); readint(d);
vector<int> ans(n);
map<int, vector<int>> vals;
forr(i,0,n) {
readint(aa);
vals[aa].push_back(i);
}
block bl(n, d);
int ret = 0;
SegmentTree2<int> seg_tree(n, [](int x, int y){ return max(x,y); }, 0);
auto it = vals.end();
while (it!=vals.begin()) {
--it;
for(int j : it->second) {
int val = 1 + seg_tree.GetEvaluation(j+1, bl.upto(j+1));
bl.add(j);
seg_tree.SetVal(j, val);
ret = max(ret, val);
}
}
cout << ret << endl;
}
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
Main.cpp: In constructor 'block::block(int, int)':
Main.cpp:115:11: warning: 'block::n' will be initialized after [-Wreorder]
115 | int n;
| ^
Main.cpp:114:11: warning: 'int block::d' [-Wreorder]
114 | int d;
| ^
Main.cpp:117:7: warning: when initialized here [-Wreorder]
117 | block(int nn, int dd) : n(nn), d(dd) {}
| ^~~~~
Main.cpp: In instantiation of 'void SegmentTree2<T>::Initialize(const std::vector<_Tp>&) [with T = int]':
Main.cpp:56:11: required from 'SegmentTree2<T>::SegmentTree2(int, std::function<T(T, T)>, T) [with T = int]'
Main.cpp:190:78: required from here
Main.cpp:84:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
84 | while(B < data.size()) {B *= 2; }
| ~~^~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |