Submission #800023

#TimeUsernameProblemLanguageResultExecution timeMemory
800023NothingXDFinancial Report (JOI21_financial)C++17
0 / 100
322 ms269264 KiB
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void debug_out(){cerr<<endl;}
template<typename Head, typename... Tail>
void debug_out(Head H, Tail... T){
	cerr << H << ' ';
	debug_out(T...);
}

#define debug(...) cerr << "(" << #__VA_ARGS__ << "): ", debug_out(__VA_ARGS__)
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define MP(x, y) make_pair(x, y)

const int maxn = 3e5 + 10;
const int lg = 20;

struct Seg{
	int l, r, ans;
	bool b;
} seg[maxn*lg];

int n, d, a[maxn], dp[maxn], lc[maxn*lg], rc[maxn*lg], root[maxn], vercnt = 1;
vector<pii> val;
void build(int v, int l, int r){
	seg[v].l = seg[v].r = seg[v].b = seg[v].ans = 0;
	if (l + 1 == r){
		return;
	}
	int mid = (l + r) >> 1;
	lc[v] = vercnt++;
	rc[v] = vercnt++;
	build(lc[v], l, mid);
	build(rc[v], mid, r);
}

Seg operator +(Seg a, Seg b){
	Seg res;
	res.l = max(a.l, (a.b? a.ans + b.l: 0));
	res.r = max(b.r, (b.b? b.ans + a.r: 0));
	res.ans = max({a.ans, b.ans, a.r + b.l});
	res.b = (a.b && b.b);
	return res;
}

void change(int v, int newv, int l, int r, int idx){
	if (l + 1 == r){
		seg[newv].l = seg[newv].r = seg[newv].ans = seg[newv].b = 1;
		return;
	}
	int mid = (l + r) >> 1;
	if (idx < mid){
		lc[newv] = vercnt++;
		rc[newv] = rc[v];
		change(lc[v], lc[newv], l, mid, idx);
	}
	else{
		lc[newv] = lc[v];
		rc[newv] = vercnt++;
		change(rc[v], rc[newv], mid, r, idx);
	}
	seg[v] = seg[v << 1] + seg[v << 1 | 1];
}

Seg get(int v, int l, int r, int ql, int qr){
	if (qr <= l || r <= ql) return {0, 0, 0, 0};
	if (ql <= l && r <= qr) return seg[v];
	int mid = (l + r) >> 1;
	return get(lc[v], l, mid, ql, qr)
		+ get(rc[v], mid, r, ql, qr);
}

vector<int> num[maxn << 2];
vector<int> mx[maxn << 2];
bool ok[maxn << 2];

void add(int v, int l, int r, int idx){
	if (idx < l || r <= idx) return;
	if (l + 1 == r){
		num[v].resize(1);
		mx[v].resize(1);
		num[v][0] = (a[idx]);
		mx[v][0] = (dp[idx]);
		ok[v] = true;
		return;
	}
	int mid = (l + r) >> 1;
	add(v << 1, l, mid, idx);
	add(v << 1 | 1, mid, r, idx);
	if (!ok[v<<1] || !ok[v<<1|1]) return;
	ok[v] = true;
	int ptl = 0, ptr = 0;
	num[v].resize(r-l);
	mx[v].resize(r-l);
	for (int i = 0; i < r-l; i++){
		if (ptr == num[v<<1|1].size() || (ptl != num[v << 1].size() && num[v<<1][ptl] < num[v<<1|1][ptr])){
			num[v][i] = num[v<<1][ptl];
			mx[v][i] = mx[v<<1][ptl];
			ptl++;
		}
		else{
			num[v][i] = num[v<<1|1][ptr];
			mx[v][i] = mx[v<<1|1][ptr];
			ptr++;
		}
	}
	for (int i = 1; i < r-l; i++){
		mx[v][i] = max(mx[v][i], mx[v][i-1]);
	}
}

int get(int v, int l, int r, int ql, int qr, int val){
	if (qr <= l || r <= ql) return 0;
	if (ql <= l && r <= qr && ok[v]){
		int idx = lower_bound(all(num[v]), val) - num[v].begin();
		if (idx != 0) return mx[v][idx-1];
		return 0;
	}
	int mid = (l + r) >> 1;
	return max(get(v << 1, l, mid, ql, qr, val)
			,get(v << 1 | 1, mid, r, ql, qr, val));
}

int main(){

	cin >> n >> d;
	for (int i = 1; i <= n; i++){
		cin >> a[i];
		val.push_back({a[i], i});
	}

	sort(all(val));

	root[n] = 0;
	build(1, 1, n+1);

	for (int i = n-1; ~i; i--){
		root[i] = vercnt++;
		change(root[i+1], root[i], 1, n+1, val[i].S);
	}

	int ans = 0;

	for (int i = 1; i <= n; i++){
		int idx = lower_bound(all(val), MP(a[i], 0)) - val.begin();
		int l = 0, r = i;
		while (l + 1 < r){
			int mid = (l + r) >> 1;
			if (get(root[idx], 1, n+1, mid, i).ans < d) r = mid;
			else l = mid;
		}
		dp[i] = get(1, 1, n+1, r, i, a[i]) + 1;
		add(1, 1, n+1, i);
		ans = max(ans, dp[i]);
	}

	cout << ans << '\n';

	return 0;
}

Compilation message (stderr)

Main.cpp: In function 'void build(int, int, int)':
Main.cpp:33:46: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
   33 |  seg[v].l = seg[v].r = seg[v].b = seg[v].ans = 0;
      |                                   ~~~~~~~~~~~^~~
Main.cpp: In function 'void add(int, int, int, int)':
Main.cpp:103:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  103 |   if (ptr == num[v<<1|1].size() || (ptl != num[v << 1].size() && num[v<<1][ptl] < num[v<<1|1][ptr])){
      |       ~~~~^~~~~~~~~~~~~~~~~~~~~
Main.cpp:103:41: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  103 |   if (ptr == num[v<<1|1].size() || (ptl != num[v << 1].size() && num[v<<1][ptl] < num[v<<1|1][ptr])){
      |                                     ~~~~^~~~~~~~~~~~~~~~~~~~~
#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...