听惯多<<1
  • 板块灌水区
  • 楼主dvsfanjo
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/10/8 18:25
  • 上次更新2024/10/8 20:51:02
查看原帖
听惯多<<1
1198462
dvsfanjo楼主2024/10/8 18:25
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = (2e5 + 20);
const ll inf = (1ll << 31) - 1;
ll n, m, op, x, y, k, a[maxn >> 2], si_ze, idx;
ll sz[maxn], l[maxn], r[maxn], val[maxn], key[maxn];
struct FHQ_Treap {
	ll root;
	void dfs(ll u) {
		if (!u)
			return;
		dfs(l[u]);
		cout << val[u] << ' ';
		dfs(r[u]);
	}
	inline ll New(ll v)
	{
		idx++;
		sz[idx] = 1;
		val[idx] = v;
		key[idx] = rand();
		return idx;
	}
	void Update(ll u)
	{
		sz[u] = sz[l[u]] + sz[r[u]] + 1;
		return;
	}
	void Split(ll u, ll v, ll &x, ll &y)
	{
		if (!u)
		{
			x = y = 0;
			return;
		}
		if (val[u] <= v)
		{
			x = u;
			Split(r[u], v, r[u], y);
		}
		else
		{
			y = u;
			Split(l[u], v, x, l[u]);
		}
		Update(u);
		return;
	}
	inline ll Merge(ll x, ll y)
	{
		if (!x || !y)
			return x | y;
		if (key[x] < key[y])
		{
			r[x] = Merge(r[x], y);
			Update(x);
			return x;
		}
		else
		{
			l[y] = Merge(x, l[y]);
			Update(y);
			return y;
		}
	}
	void Insert(ll v)
	{
		ll x, y, z;
		z = New(v);
		Split(root, v, x, y);
		root = Merge(Merge(x, z), y);
		return;
	}
	void Delete(ll v)
	{
		ll x, y, z;
		Split(root, v, x, y);
		Split(x, v - 1, x, z);
		z = Merge(l[z], r[z]);
		root = Merge(Merge(x, z), y);
		return;
	}
	inline ll Rank(ll v)
	{
		ll x, y, ans;
		Split(root, v - 1, x, y);
		ans = sz[x] + 1;
		root = Merge(x, y);
		return ans;
	}
	inline ll K_th(ll u, ll k)
	{
		if (!u)
			return 1;
		if (sz[l[u]] + 1 == k)
			return val[u];
		if (k <= sz[l[u]])
			return K_th(l[u], k);
		return K_th(r[u], k - sz[l[u]] - 1);
	}
	inline ll Pre(ll v)
	{
		ll x, y, ans;
		if (K_th(root, 1) >= v)
			return -inf;
		Split(root, v - 1, x, y);
		ans = K_th(x, sz[x]);
		root = Merge(x, y);
		return ans;
	}
	inline ll Suc(ll v)
	{
		ll x, y, ans;
		if (K_th(root, sz[root]) <= v)
			return inf;
		Split(root, v, x, y);
		ans = K_th(y, 1);
		root = Merge(x, y);
		return ans;
	}
};
struct SegTree {
	FHQ_Treap t[maxn];
	void build(ll l, ll r, ll i) {
		for (int ii = l; ii <= r; ii++)
			t[i].Insert(a[ii]);
		if (l == r)
			return;
		ll mid = (l + r) >> 1;
		build(l, mid, i << 1);
		build(mid + 1, r, i << 1 | 1);
		return;
	}
	void update(ll l, ll r, ll i, ll w, ll k) {
		t[i].Delete(a[w]);
		t[i].Insert(k);
		if (l == r && l == w) {
			a[w] = k;
			return;
		}
		ll mid = (l + r) >> 1;
		if (w <= mid)
			update(l, mid, i << 1, w, k);
		else
			update(mid + 1, r, i << 1 | 1, w, k);
		return;
	}
	ll rank(ll l, ll r, ll i, ll a, ll b, ll k) {
		if (a <= l && r <= b)
			return t[i].Rank(k) - 1;
		ll mid = (l + r) >> 1, ans = 0;
		if (a <= mid)
			ans += rank(l, mid, i << 1, a, b, k);
		if (mid < b)
			ans += rank(mid + 1, r, i << 1 | 1, a, b, k);
		return ans;
	}
	ll k_th(ll l, ll r, ll k) {
		ll x = 0, y = 1e9, ans = - 1;
		while (x <= y) {
//			cout << x << ' ' << y << '\n';
//			Sleep(100);
			ll mid = (x + y) >> 1;
			if (rank(1, n, 1, l, r, mid) < k)
			{
				ans = mid;
				x = mid + 1;
			}
			else
				y = mid - 1;
		}
		return ans;
	}
	ll pre(ll l, ll r, ll i, ll a, ll b, ll k) {
		if (a <= l && r <= b)
			return t[i].Pre(k);
		ll mid = (l + r) >> 1, ans = -1e18;
		if (a <= mid)
			ans = max(ans, pre(l, mid, i << 1, a, b, k));
		if (mid < b)
			ans = max(ans, pre(mid + 1, r, i << 1 | 1, a, b, k));
		return ans;
	}
	ll suc(ll l, ll r, ll i, ll a, ll b, ll k) {
		
		if (a <= l && r <= b) {
	//		cout << l << ' ' << r << ' ' <<  t[i].Suc(k) << '\n';
			return t[i].Suc(k);
		}
			
		ll mid = (l + r) >> 1, ans = 1e18;
		if (a <= mid)
			ans = min(ans, suc(l, mid, i << 1, a, b, k));
		if (mid < b)
			ans = min(ans, suc(mid + 1, r, i << 1 | 1, a, b, k));
		return ans;
	}
} tree;
inline ll read(){
    ll x=0,tmp=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') tmp=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        x=(x<<3)+(x<<1)+(ch^48);
        ch=getchar();
    }
    return tmp*x;
}

inline void write(ll x){
    if(x<0){
        putchar('-');
        x=-x;
    }
    ll y=10,len=1;
    while(y<=x){
        y=(y<<3)+(y<<1);
        len++;
    }
    while(len--){
        y/=10;
        putchar(x/y+48);
        x%=y;
    }
}
int main() {
	
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		a[i] = read();
	tree.build(1, n, 1);
//	cout << tree.suc(1, n, 1, 2, 8, 5) << '\n';
	while  (m--) {
		op = read(), x = read(), y = read();
		if (op != 3)
			k = read();
		if (op == 1)
			cout << tree.rank(1, n, 1, x, y, k) + 1 << '\n';
		else if (op == 2)
			cout << tree.k_th(x, y, k) << '\n';
		else if (op == 3)
			tree.update(1, n, 1, x, y);
		else if (op == 4)
			cout << tree.pre(1, n, 1, x, y, k) << '\n';
		else if (op == 5)
			cout << tree.suc(1, n, 1, x, y, k) << '\n';
	}
	return 0;
}
/*
9 1
4 2 2 10 9 4 0 1 1
5 2 8 5


4 2 2 10 9 4 0 1 1
4 2 2 10 9		4 0 1 1
4 2 2		10 9		4 0		1 1
4 2		2 	10 9 	4 	0	1 	1
4	2



*/

输入都 MLE ,有快读,不知道什么问题。

link

2024/10/8 18:25
加载中...