1. 程式人生 > 資訊 >6999 元,樂視推出新品 letvM65:MiniLED 技術、獨創 576 分割槽

6999 元,樂視推出新品 letvM65:MiniLED 技術、獨創 576 分割槽

對,你沒看錯,題目就這。。。

一眼看上去,似乎是個和之前一樣的板子,然後再一看。。。


...為啥還有區間要求???

萬惡之源 \(\Rightarrow [l,r] \huge{[l,r]}\)

然後,事情就變得不簡單了。。。


不就是個 \(250\) 行唄。。。

不就是個線段樹上每一個區間節點上套一個 \(splay\;tree\) 唄。。。

不就是死活調不對唄。。。

不就是輸出一堆 \(2147483647\) 唄。。。

不就是。。。。


當我精神幾近崩潰的時候,\(zxb\) 出現,他是來拯救我的。。。

用雙指標

。。。。


將其趕走之後,在歷經下午,晚上,早讀,上午將近 \(6\)

小時的努力下,終於。。。。

\(RE\)

(此處省略 \(10000\) 字,請自行腦補)


但最後憑藉堅強的毅力 f**k除錯法,終於調出了樣例,本以為會 然而卻, \(\huge{\text{心中狂喜}}\)

然鵝連luogu最差解都算不上

主要做法就是對於整個序列建造一顆線段樹,用來劃分區間。

之後對於整個序列進行一個建樹操作,就可以建造出每一個可行序列。

在每個序列當中,並不需要有什麼權值。

只需要一個 \(root\) 來維護 \(splay\;tree\) 的根。

這樣每一個 \(splay\;tree\) 就可以劃分清楚,互不干擾。

建樹的時候在每個點再建造一棵 \(splay\;tree\)

用來維護那要求的 \(5\) 個操作,記得還要 \(insert\) 一個 \(2147483647\) 防止找不到 \(pre\)\(next\)

之後的 \(kth\) \(rank\) \(rotatr\) \(splay\) \(search\) \(pre\) \(next\) \(del\) 操作就大同小異了,其實就是在需要使用根節點的函式多傳一個 \(node\) 引數用來區分。

然後線段樹操作也就是 \(segins\) \(segkth\) \(segrk\) \(segpre\) \(segnext\) \(build\)

也就是將近20個函式,一點都不多。。。

真 不多


然後就可以開始漫長的 \(debug\) 過程了,這才是全部的 \(90%\) 才對。。。

當你這道題目除錯完看到時,比做出任何一道題都有成就感。。。

所以來 \(k\) \(k\) 我的小程式碼ba。。。。

#include<bits/stdc++.h>
using namespace std;
//#define int long long
#define debug cout<<"debug"<<endl
#define freopen eat2 = freopen
#define scanf eat1 = scanf
#define INF 2147483647
#define inf INF
#define cao cout<<endl
namespace xin_io
{
	#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
	#define scanf eat1 = scanf 
	#define freopen eat2 = freopen
	char buf[1<<20],*p1 = buf,*p2 = buf;FILE *eat2;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile(){freopen("o.txt","w",stdout);}
	inline int get()
	{
		int s = 0,f = 1;register char ch = gc();
		while(!isdigit(ch))
		{if(ch == '-') f = -1;ch = gc();}
		while(isdigit(ch))
		{s = s * 10 + ch - '0';ch = gc();}return s * f;
	}
}
using namespace xin_io; int eat1;
static const int maxn = 1e6+10,mod = 1e6;
inline int min(int x,int y) {return x > y ? y : x;} inline int max(int x,int y) {return x > y ? x : y;}
#define ls(x) t[x].son[0]
#define rs(x) t[x].son[1]
namespace xin
{
	#define pushup(x) t[x].size = t[ls(x)].size + t[rs(x)].size + t[x].tot
	class xin_splay{public:int size, tot, val,son[2],fa;}t[maxn * 50];
	int rt[maxn];
	int a[maxn], n, m, cnt;
	inline void rotate(int x)
	{
		register int y = t[x].fa,z = t[y].fa;
		register int ki = t[y].son[1] == x;
		t[z].son[t[z].son[1] == y] = x; t[x].fa = z;
		t[y].son[ki] = t[x].son[ki xor 1]; t[t[x].son[ki xor 1]].fa = y;
		t[x].son[ki xor 1] = y; t[y].fa = x;
		pushup(y); pushup(x);
	}
	inline void splay( int x, int goal, int node ) 
	{
		while( t[x].fa != goal ) 
		{
			int y = t[x].fa,z = t[y].fa;
			if(z != goal) (t[z].son[1] == y) ^ (t[y].son[1] == x) ? rotate(x) : rotate(y);
			rotate(x); 
		}
		if(!goal) rt[node] = x;
	}
	inline int init( int v, int fa ) {t[++cnt].val = v, t[cnt].fa = fa, t[cnt].tot = 1;pushup(cnt); return cnt;}
	inline void insert( int x, int node ) 
	{
		int u = rt[node],fa = 0;
		if(!u) { u = init(x, 0), rt[node] = u; return ;}
		while(u and t[u].val != x) fa = u, u = t[u].son[t[u].val < x];
		if(u) t[u].tot ++;
		else
		{	
			u = init(x, fa);
			if(fa) t[fa].son[t[fa].val < x] = u;
		}
		splay(u,0,node ); 
	}
	inline void search( int x, int node) 
	{
		int u = rt[node];  if(!u) return ;
		while( t[u].son[t[u].val < x] and t[u].val != x) 
			u = t[u].son[t[u].val < x];
		splay( u, 0, node );
	}
	inline int next( int x, int typ, int node )
	{
		search(x, node); int u = rt[node];
		if((typ and t[u].val < x) || (!typ and t[u].val > x)) return u;
		u = t[u].son[typ ^ 1];
		while(t[u].son[typ]) u = t[u].son[typ];
		return u;
	}
	inline void del( int x, int node) 
	{
		int u = rt[node], pre = next(x, 1, node), nxt = next(x,0,node);
		splay(nxt, 0, node); splay(pre, nxt, node);
		int pos = t[pre].son[1];
		if(t[pos].tot > 1) -- t[pos].tot, splay(pos, 0, node);
		else t[pre].son[1] = 0;
		pushup(pre); 
	}
	inline void build(int node,int l,int r)
	{
		insert(inf,node); insert(-inf,node);
		if(l == r) return;
		register int mid = (l + r) >> 1;
		build(node<<1,l,mid); build(node << 1| 1,mid+1,r);
	}
	inline void segins(int node,int l,int r,int k,int val)
	{
		register int mid = (l + r) >> 1;
		insert(val,node);if(l == r) return ;
		if(mid >= k) segins(node << 1,l,mid,k,val);
		else segins(node << 1| 1,mid+1,r,k,val);
	}
	inline int segrk(int node,int l,int r,int k,int ql,int qr)
	{
		if(qr < l or ql > r) return 0;
		if(ql <= l and qr >= r) 
		{
			search(k,node); register int u = rt[node];
			if(t[u].val >= k) return t[ls(u)].size - 1;
			else return t[ls(u)].size + t[u].tot - 1;
		}
//		cout<<node<<' '<<l<<' '<<r<<endl;
		register int mid = (l + r) >> 1;
		return segrk(node << 1,l,mid,k,ql,qr) + segrk(node << 1| 1,mid+1,r,k,ql,qr);
	}
	inline void segupd(int node,int l,int r,int pos,int val)
	{
		del(a[pos],node); insert(val,node);
		if(l == r and r == pos) {a[pos] = val;return ;}
		register int mid = (l + r ) >> 1;
		if(mid >= pos) segupd(node << 1,l,mid,pos,val);
		else segupd(node << 1| 1,mid+1,r,pos,val);
	}
	inline int segnxt(int node,int l,int r,int ql,int qr,int k)
	{
		if(l > qr or r < ql) return inf;
		if(l >= ql and r <= qr) return t[next(k,0,node)].val;
		register int  mid = (l + r )>> 1;
		return min(segnxt(node << 1,l,mid,ql,qr,k) , segnxt(node << 1 | 1,mid + 1,r,ql,qr,k));
	}
	inline int segpre(int node,int l,int r,int ql,int qr,int k)
	{
		if(l > qr or r < ql) return -inf;
		if(l >= ql and r <= qr) return t[next(k,1,node)].val;
		register int mid = (l + r) >> 1;
		return max(segpre(node << 1,l,mid,ql,qr,k) , segpre(node << 1| 1,mid+1,r,ql,qr,k));
	}
	inline int segkth(int ql,int qr,int k)
	{
		register int l = 0,r = 1e8,ret;
		while(l <= r)
		{
			register int mid = (l + r) >> 1;
			register int judge = segrk(1,1,n,mid,ql,qr) + 1;
			if(judge > k) r = mid - 1;
			else l = mid + 1, ret = mid;
		}
		return ret;
	}
	inline void check()
	{
		for(register int i=1;i<=cnt;++i)
			cout<<"i = "<<i<<" t[i].val = "<<t[i].val<<" t[i].size = "<<t[i].size<<endl;
		cout<<endl;
	}
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();
	#endif
		n = get(); m = get(); build(1,1,n);
//		check();
		for(register int i=1;i<=n;++i) a[i] = get(),segins(1,1,n,i,a[i]);
//		check();
		for(register int i=1;i<=m;++i)
		{
			register int op = get();
			if(op == 1)
			{
				register int l = get(),r = get(),x = get();
				printf("%d\n",segrk(1,1,n,x,l,r) + 1);
			}
			if(op == 2)
			{
				register int l = get(),r = get(),k = get();
				printf("%d\n",segkth(l,r,k));
			}
			if(op == 3)
			{
				register int pos = get(),x = get();
				segupd(1,1,n,pos,x);
			}
			if(op == 4)
			{
				register int l = get(),r = get(),x = get();
				printf("%d\n",segpre(1,1,n,l,r,x));
			}
			if(op == 5)
			{
				register int l = get(),r = get(),x = get();
				printf("%d\n",segnxt(1,1,n,l,r,x));
			}	
		}
		return 0;
	}
}
signed main() {return xin::main();}

\(\huge{\color{red}{\text{真好玩}}}\)