제출 #1127476

#제출 시각아이디문제언어결과실행 시간메모리
1127476O_ElmasryGlobal Warming (CEOI18_glo)C++20
0 / 100
370 ms48216 KiB
#include <bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
using namespace std;
#ifdef LOCAL
#include "debug.h"
#else
#define dbg(...)
#endif
#define endl '\n'
#define int int64_t
const long long mod = 1000000007, MaxN = 200005, INF = 1e18;
struct Cordinate_Compression
{
  set<int> vals;
  map<int, int> val_to_cord, cord_to_val;
  void init(set<int> s)
  {
    vals = s;
    int idx = 1;
    for (auto i : vals)
    {
      cord_to_val[idx] = i;
      val_to_cord[i] = idx++;
    }
  }
  int incr(int x)
  {
    return val_to_cord[x];
  }
  int decr(int idx)
  {
    return cord_to_val[idx];
  }
  int lower_bound(int x){
    return *--vals.upper_bound(x);
  }
};
template<typename T>
struct Segment_Tree{
  int sz = 1, N;
  T Neutral;
  vector<T>tree;
  function<T(T, T)> merge;
  Segment_Tree(int _N, function< T (T, T) >_merge, T _Neutral = 0){
    merge = _merge;
    while(sz < _N)sz *= 2;
    N = sz * 2;
    tree.resize(N);
    Neutral = _Neutral;
  }
  #define left node * 2 + 1
  #define right node * 2 + 2
  void build(int idx, T val, int node, int l, int r){
    if(l == r)return void(tree[node] = val);
    int mid = l + r >> 1;
    if(idx <= mid)build(idx, val, left, l, mid);
    else build(idx, val, right, mid + 1, r);
    tree[node] = merge(tree[left], tree[right]);
  }
  void build(int idx, int val){
    build(idx, val, 0, 0, sz - 1);
  }

  T get(int lq, int rq, int node, int l, int r){
    if(l > rq || r < lq)return Neutral;
    if(l >= lq && r <= rq)return tree[node];
    int mid = l + r >> 1;
    return merge(get(lq, rq, left, l, mid), get(lq, rq, right, mid + 1, r));
  }
  T get(int lq, int rq){
    return get(lq, rq, 0, 0, sz - 1);
  }
  #undef left
  #undef right
};
void solve()
{
  int N, x;
  cin >> N >> x;
  vector<int> a(N + 1), lis, lds, best(N + 1);
  map<int, multiset<int>> st;
  Cordinate_Compression cc;
  set<int>s(a.begin(), a.end());
  s.insert(0), s.insert(INF);
  cc.init(s);
  Segment_Tree<int>seg(N + 3, [](int a, int b){
    return max(a, b);
  }, 0);
  for (int i = 1; i <= N; i++)
  {
    cin >> a[i];
    if (i == 1)
    {
      lis.push_back(a[i]);
      best[i] = 1;
      st[a[i]].insert(best[i]);
      continue;
    }
    int pos = lower_bound(lis.begin(), lis.end(), a[i]) - lis.begin();
    if (pos == lis.size())
    {
      lis.push_back(a[i]);
    }
    else
    {
      lis[pos] = a[i];
    }
    best[i] = pos + 1;
    st[a[i]].insert(best[i]);
  }
  for(auto [x, y] : st){
    seg.build(cc.incr(x), *--y.end());
  }
  int ans = seg.get(0, N + 1);
  for(int i = N;i >= 1;i--){
    int pos = a[i] + x - 1;
    int lb = cc.lower_bound(pos);
    int cur = seg.get(0, cc.incr(lb));
    if(lds.empty()){
      lds.push_back(a[i]);
      ans = max(ans, cur + 1);
      continue;
    }
    int L = -1, R = lds.size();
    while(L + 1 < R){
      int mid = L + R >> 1;
      if(lds[mid] > a[i]){
        L = mid;
      }
      else{
        R = mid;
      }
    }
    dbg(cur, L, a[i]);
    ans = max(ans, cur + L + 2);
  }
  cout << ans << endl;
}
signed main()
{
  ios::sync_with_stdio(0);
  cin.tie(nullptr);
  cout.tie(nullptr);
#ifdef LOCAL
  FileRedirect("test");
#endif
  // freopen("file.in","r",stdin);
  // freopen("file.out","w",stdout);
  int tc = 1;
  // cin >> tc;
  while (tc--)
    solve();
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...