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\)
之後的 \(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{真好玩}}}\)