P4755 MLE两个点求调
  • 板块学术版
  • 楼主AK_heaven
  • 当前回复3
  • 已保存回复3
  • 发布时间2024/3/2 17:37
  • 上次更新2024/3/2 19:42:56
查看原帖
P4755 MLE两个点求调
799877
AK_heaven楼主2024/3/2 17:37
#include <bits/stdc++.h>
//#define int long long
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;

int a[maxn], n; ll ans; int l[maxn], r[maxn];

int build() {
	int st[maxn], tp = 0, k = 0;
	for(int i = 1; i <= n; i++) {
		k = tp;
		while(k > 0 && a[st[k]] < a[i]) k--;
		if(k) r[st[k]] = i;
		if(k < tp) l[i] = st[k+1];
		st[++k] = i;
		tp = k;
	}
	return st[1];
}

vector<int> v[maxn];

vector<int> st(vector<int> a, vector<> b) {
	int x = a.size();
	int y = b.size();
	vector<int> ret(x+y);
	int i = 0, j = 0, k = 0;
	while(i < x && j < y) {
		if(a[i] > b[j])
		  ret[k++] = b[j++];
		else 
		  ret[k++] = a[i++];
	}
	while(i < x) ret[k++] = a[i++];
	while(j < y) ret[k++] = b[j++];
	return ret;
}

void dfs(int u) {
	if(u == 0) return ;
	dfs(l[u]); dfs(r[u]);
	vector<int> v1, v2;
	v1 = v[l[u]];
	v2 = v[r[u]];
	v[l[u]].clear();
	v[r[u]].clear();
	if(v1.size() > v2.size()) swap(v1, v2);
	v1.push_back(a[u]);
	v[u] = st(v1, v2);
	v2.push_back(a[u]);
	for(int ai : v1) {
		int k = a[u]/ai;
//		for(int aj : v2) cout << aj << '\n';
		int c = upper_bound(v2.begin(), v2.end(), k)-v2.begin();
		ans += c;
//		cout << ai << ' ' << k << ' ' << a[u] << ' ' << c << '\n';
	}
}

signed main() {
	cin >> n;
	for(int i = 1; i <= n; i++) 
	  cin >> a[i];
	dfs(build());
	cout << ans;
	return 0;
}
2024/3/2 17:37
加载中...