結果
| 問題 |
No.1188 レベルX門松列
|
| コンテスト | |
| ユーザー |
IKyopro
|
| 提出日時 | 2020-08-22 13:36:17 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 387 ms / 2,000 ms |
| コード長 | 2,797 bytes |
| コンパイル時間 | 2,900 ms |
| コンパイル使用メモリ | 210,056 KB |
| 最終ジャッジ日時 | 2025-01-13 07:47:18 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 21 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template <class T> using vvvec = vector<vvec<T>>;
template<typename Monoid,typename F>
class SegmentTree{
private:
int sz;
vector<Monoid> seg;
const F op;
const Monoid e;
public:
SegmentTree(int n,const F op,const Monoid &e):op(op),e(e){
sz = 1;
while(sz<=n) sz <<= 1;
seg.assign(2*sz,e);
}
void set(int k, const Monoid &x){
seg[k+sz] = x;
}
void build(){
for(int i=sz-1;i>0;i--){
seg[i] = op(seg[2*i],seg[2*i+1]);
}
}
void update(int k,const Monoid &x){
k += sz;
seg[k] = x;
while(k>>=1){
seg[k] = op(seg[2*k],seg[2*k+1]);
}
}
Monoid query(int l,int r){
Monoid L = e,R = e;
for(l+=sz,r+=sz;l<r;l>>=1,r>>=1){
if(l&1) L = op(L,seg[l++]);
if(r&1) R = op(seg[--r],R);
}
return op(L,R);
}
};
template<class T>
class Compress {
int N;
map<T,int> idx;
map<int,T> value;
vec<T> v;
vec<T> cmp;
public:
Compress(){}
void add(T x){v.push_back(x);}
void build(){
for(auto &x:v) cmp.push_back(x);
sort(cmp.begin(),cmp.end());
cmp.erase(unique(cmp.begin(),cmp.end()),cmp.end());
N = cmp.size();
for (int i=0;i<N;i++) idx[cmp[i]] = i;
}
int id(T val) {return idx[val];}
T val(int id) {return cmp[id];}
int size(){return N;}
};
int main(){
cin.tie(0);
ios::sync_with_stdio(false);
int N;
cin >> N;
vec<int> A(N);
Compress<int> cmp;
for(auto& x:A){
cin >> x;
cmp.add(x);
}
cmp.add(0);
cmp.build();
vec<int> L(N+1),R(N+1);
int M = cmp.size();
SegmentTree seg(N,[](int a,int b){return max(a,b);},0);
for(int i=0;i<N;i++){
int n = seg.query(cmp.id(A[i])+1,M);
L[i+1] = n+1;
seg.update(cmp.id(A[i]),n+1);
}
for(int i=0;i<M;i++) seg.set(i,0);
seg.build();
for(int i=N-1;i>=0;i--){
int n = seg.query(cmp.id(A[i])+1,M);
R[i] = n+1;
seg.update(cmp.id(A[i]),n+1);
}
int ans = 0;
for(int i=0;i<N;i++) ans = max(ans,min(L[i+1]-1,R[i]-1));
for(int i=0;i<M;i++) seg.set(i,0);
seg.build();
for(int i=0;i<N;i++){
int n = seg.query(0,cmp.id(A[i]));
L[i+1] = n+1;
seg.update(cmp.id(A[i]),n+1);
}
for(int i=0;i<M;i++) seg.set(i,0);
seg.build();
for(int i=N-1;i>=0;i--){
int n = seg.query(0,cmp.id(A[i]));
R[i] = n+1;
seg.update(cmp.id(A[i]),n+1);
}
for(int i=0;i<N;i++) ans = max(ans,min(L[i+1]-1,R[i]-1));
cout << ans << "\n";
}
IKyopro