• 题目:二逼平衡树 及其启示


    改变数据结构的写法了, 以后就把所有抽象数据类型塞到namespace
    里去了qwq

    // WA、 TEL 且 RE 的代码, 以后再调
    #include<bits/stdc++.h>
    using namespace std;
    const int maxlog = 20;
    
    namespace fhq {
    	
    	const int maxn = maxlog * 50000 + 1001;
    	int siz[maxn] ,ls[maxn], rs[maxn], rnd[maxn], val[maxn], tot;
    	
    	int newnode(int v)
    	{
    		val[++tot] = v; rnd[tot] = rand(); siz[tot] = 1;
    //		ls[tot] = rs[tot] = 0;
    		return tot;
    	}
    	
    	void update(int k)
    	{
    		siz[k] = siz[ls[k]] + siz[rs[k]] + 1;
    	}
    	
    	void merge(int &k,int a, int b)
    	{
    		if(!a || !b)
    		{
    			k = a + b;
    			return;
    		}
    		if(rnd[a] < rnd[b])
    		{
    			k = a;
    			merge(rs[a], rs[a], b);
    		}
    		else
    		{
    			k = b;
    			merge(ls[b], a, ls[b]);
    		}
    		update(k);
    	}
    	
    	void split(int k, int &a, int &b, int weight)
    	{
    		if(!k)
    		{
    			a = b = 0;
    			return;
    		}
    		if(val[k] <= weight)
    		{
    			a = k;
    			split(rs[a], rs[a], b, weight);
    		}
    		else
    		{
    			b = k;
    			split(ls[b], a, ls[b], weight);
    		}
    		update(k);
    	}
    	
    	void ins(int &rt, int v)
    	{
    		int a = 0, b = 0;
    		split(rt, a, b, v);
    		merge(a, a, newnode(v));
    		merge(rt, a, b);
    	}
    	
    	int quesrank(int &rt, int k)
    	{
    		int a = 0, b = 0;
    		split(rt, a, b, k-1);
    		int ret = siz[a];
    		merge(rt, a, b);
    		return ret;
    	}
    	
    	void del(int &rt,int k)
    	{
    		int a = 0, b = 0, c = 0;
    		split(rt, a, c, k);
    		split(a, a, b, k-1);
    		merge(b, ls[b], rs[b]);
    		merge(a, a, b);
    		merge(rt, a, c);
    	}
    	
    	int ma(int p)
    	{
    		if(!siz[p]) return -2147483647;
    		while(rs[p]) p=rs[p];
    		return val[p];
    	}
    	
    	int mi(int p)
    	{
    		if(!siz[p]) return 2147483647;
    		while(ls[p]) p=ls[p];
    		return val[p];
    	}
    	
    	int pre(int &rt,int k)
    	{
    		int a = 0, b = 0;
    		split(rt, a, b, k-1);
    		int ret = ma(a);
    		merge(rt, a, b);
    		return ret;
    	}
    	
    	int nxt(int &rt,int k)
    	{
    		int a = 0, b = 0;
    		split(rt, a, b, k);
    		int ret = mi(b);
    		merge(rt, a, b);
    		return ret;
    	}
    	
    }
    
    namespace seg {
    	
    	const int maxn = maxlog * 50000;
    	
    	int ls[maxn], rs[maxn], fhqrt[maxn];
    	int rt, tot, n;
    	
    	int m, vec[5005];
    	
    	void build(int* a, int &u, int l,int r)
    	{
    		if(!u) u = ++tot;
    		//
    		for(int i=l; i<=r; ++i) fhq::ins(fhqrt[u], a[i]);
    		//build fhq
    		if(l == r) return;
    		int mid = (l + r) >> 1;
    		build(a, ls[u], l, mid);
    		build(a, rs[u], mid + 1, r);
    	}
    	
    	void vis(int u, int l,int r,int x,int y)
    	{
    		if(x<=l && r<=y) {
    			vec[++m] = u;
    			return;
    		}
    		int mid = (l + r) >> 1;
    		if(x <= mid) vis(ls[u], l, mid, x, y);
    		if(y > mid) vis(rs[u], mid + 1, r, x, y);
    	}
    	
    	void getvec(int l,int r)
    	{
    		m = 0;
    		vis(rt, 1, n, l, r);
    	}
    	
    	int quesrank(int l,int r,int k)
    	{
    		getvec(l, r);
    		int ret = 0;
    		for(int i=1; i<=m; ++i)
    		{
    			ret += fhq::quesrank(fhqrt[vec[i]], k);
    		}
    		return ret + 1;
    	}
    	
    	int queskth(int l,int r,int k)
    	{
    		int L = 0, R = 100000000;
    		while(L!=R)
    		{
    			int mid = (L+R+1) >> 1;
    			if(quesrank(l, r, mid) > k) R = mid-1;
    			else L = mid;
    		}
    		return L;
    	}
    	
    	//modify(seg::rt, 1, n, pos, k);
    	int modify(int u, int l,int r,int pos,int k)
    	{
    		
    		if(l == r) {
    			int ret = fhq::val[fhqrt[u]];
    			fhq::del(fhqrt[u], ret);
    			fhq::ins(fhqrt[u], k);
    			return ret;
    		}
    		int mid = (l+r) >> 1; int d;
    		if(pos<=mid) d = modify(ls[u], l, mid, pos, k);
    		else d = modify(rs[u], mid + 1, r, pos, k);
    		fhq::del(fhqrt[u], d);
    		fhq::ins(fhqrt[u], k);
    		
    		return 1;
    		
    	}
    	
    	int quesprev(int l,int r,int k)
    	{
    		getvec(l, r);
    		int ret = -2147483647;
    		for(int i=1; i<=m; ++i)
    		{
    			ret = max(ret, fhq::pre(fhqrt[vec[i]], k));
    		}
    		return ret;
    	}
    	
    	int quesnext(int l,int r,int k)
    	{
    		getvec(l, r);
    		int ret = 2147483647;
    		for(int i=1; i<=m; ++i)
    		{
    			ret = min(ret, fhq::nxt(fhqrt[vec[i]], k));
    		}
    		return ret;
    	} 
    	
    }
    
    int a[50005], n, m;
    
    int main()
    {
    	
    	srand((unsigned)time(0));
    	
    	scanf("%d%d", &n, &m);
    	for(int i=1; i<=n; ++i) scanf("%d", &a[i]);
    	seg::build(a, seg::rt, 1, n);
    	seg::n = n;
    	
    	while(m--)
    	{
    		int opt; scanf("%d", &opt);
    		if(opt == 1)
    		{
    			int l, r, k; scanf("%d%d%d", &l, &r, &k);
    			cout << seg::quesrank(l, r, k) << '
    ';
    		}
    		if(opt == 2)
    		{
    			int l, r, k; scanf("%d%d%d", &l, &r, &k);
    			cout << seg::queskth(l, r, k) << '
    ';
    		}
    		if(opt == 3)
    		{
    			int pos, k; scanf("%d%d", &pos, &k);
    			seg::modify(seg::rt, 1, n, pos, k);
    		}
    		if(opt == 4)
    		{
    			int l, r, k; scanf("%d%d%d", &l, &r, &k);
    			cout << seg::quesprev(l, r, k) <<'
    ';
    		}
    		if(opt == 5)
    		{
    			int l, r, k; scanf("%d%d%d", &l, &r, &k);
    			cout << seg::quesnext(l, r, k) <<'
    ';
    		}
    	}
    	
    	return 0;
    	
    }
    
  • 相关阅读:
    流量控制--2.传统的流量控制元素
    流量控制--1.概览
    Opentelemetry Collector的配置和使用
    高德全链路压测——精准控压的建设实践
    高德全链路压测——语料智能化演进之路
    业内首发车道级导航背后——详解高精定位技术演进与场景应用
    浅析云控平台画面传输的视频流方案
    关于卫星定位,你想知道的一切
    Pod容器中安装软件包
    面试应该怎么问问题?
  • 原文地址:https://www.cnblogs.com/tztqwq/p/12149438.html
Copyright © 2020-2023  润新知