都是泪,调了一晚。代码能力++。
查询区间排名k,时间复杂度nlog³n,bzoj能A,但是tyvj TLE 两个点,求各路大神指错打脸。
另外推荐一个OJ http://cogs.pro/cogs/ 给数据,很良心。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
#define maxn 1000005
//#include<windows.h>
using namespace std;
stack<int> S;
inline void read(int &a)
{
a=0;int h=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') h=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
a*=10;a+=c-'0';
c=getchar();
}
a*=h;
}
struct xds
{
int l,r;
int root;
}tree[400005];
int a[50005];
int tot;
int key[maxn],sz[maxn],cnt[maxn];
int fa[maxn],ch[maxn][2];
int D,inf=1e9;
int Min=1e9,Max=0;
//===============================================
bool dir(int x)
{return x==ch[fa[x]][1];}
void up(int x)
{sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x];}
void rotate(int x)
{
bool b=dir(x);
int y=fa[x];
int z=fa[y];
int a=ch[x][!b];
if(z) ch[z][dir(y)]=x;
else tree[D].root=x;
fa[x]=z;ch[x][!b]=y;
fa[y]=x;ch[y][b]=a;
if(a) fa[a]=y;
up(y);up(x);
}
void Splay(int x)
{
while(fa[x]!=tree[D].root)
{
int y=fa[x];int z=fa[y];
if(z==tree[D].root)
rotate(x);
else
{
bool b=dir(x),c=dir(y);
if(b^c) {rotate(x);rotate(x);}
else {rotate(y);rotate(x);}
}
}
}
void splay(int x)
{
while(x!=tree[D].root)
{
if(fa[x]==tree[D].root)
rotate(x);
else
{
int y=fa[x];
bool b=dir(x),c=dir(y);
if(b^c) {rotate(x);rotate(x);}
else {rotate(y);rotate(x);}
}
}
}
void insert(int x,int &y,int last)
{
if(y==0)
{
if(!S.empty())
{
y=S.top();
S.pop();
}
else y=++tot;
key[y]=x;fa[y]=last;
sz[y]=1;cnt[y]=1;
ch[y][0]=0;ch[y][1]=0;
// splay(y);
return ;
}
if(x==key[y])
{
sz[y]++;
cnt[y]++;
// splay(y);
return ;
}
sz[y]++;
if(x>key[y])insert(x,ch[y][1],y);
else insert(x,ch[y][0],y);
}
int d,pre,nxt;
int t1,t2;
void f_pre(int x)
{
for(;x;x=ch[x][key[x]<d])
if(key[x]<d){pre=max(pre,key[x]);t1=x;}
}
void f_nxt(int x)
{
for(;x;x=ch[x][key[x]<=d])
if(key[x]>d){nxt=min(nxt,key[x]);t2=x;}
}
//===============================================
void dfs(int x,int y,int last)
{
if(x==0) return ;
fa[y]=last;key[y]=key[x];
sz[y]=sz[x];cnt[y]=cnt[x];
if(ch[x][1])
{
ch[y][1]=++tot;
dfs(ch[x][1],ch[y][1],y);
}
if(ch[x][0])
{
ch[y][0]=++tot;
dfs(ch[x][0],ch[y][0],y);
}
}
void build(int dq,int l,int r)
{
tree[dq].l=l;
tree[dq].r=r;
tree[dq].root=++tot;
if(l==r)
{
sz[tot]=1;cnt[tot]=1;key[tot]=a[l];
fa[tot]=tree[dq>>1].root;
return ;
}
int mid=(l+r)>>1;
build(dq<<1,l,mid);
build(dq<<1|1,mid+1,r);
D=dq;
dfs(tree[dq<<1].root,tree[dq].root,0);
for(int i=mid+1;i<=r;i++)
insert(a[i],tree[dq].root,0);
}
//===============================================
int L,R,X;
int CNT;
int f_n_r(int dq)//1
{
if(tree[dq].l>=L&&tree[dq].r<=R)
{
t1=inf;d=X;pre=-inf;
f_pre(tree[dq].root);
if(t1==inf) return 0;
D=dq;splay(t1);
return sz[t1]-sz[ch[t1][1]];
}
int ans=0;
int mid=(tree[dq].l+tree[dq].r)>>1;
if(mid>=L) ans+=f_n_r(dq<<1);
if(mid<R) ans+=f_n_r(dq<<1|1);
return ans;
}
void find_pre(int dq)
{
if(tree[dq].l>=L&&tree[dq].r<=R)
{
f_pre(tree[dq].root);
return ;
}
int mid=(tree[dq].l+tree[dq].r)>>1;
if(mid>=L) find_pre(dq<<1);
if(mid<R) find_pre(dq<<1|1);
}
void find_nxt(int dq)
{
if(tree[dq].l>=L&&tree[dq].r<=R)
{
f_nxt(tree[dq].root);
return ;
}
int mid=(tree[dq].l+tree[dq].r)>>1;
if(mid>=L) find_nxt(dq<<1);
if(mid<R) find_nxt(dq<<1|1);
}
//===============================================
void Find(int i,int k)
{
for(;i;i=ch[i][key[i]<k])
if(key[i]==k)
{splay(i);return ;}
}
int pos;
void del()
{
int dq=tree[D].root;
if(cnt[dq]>1)
{cnt[dq]--;sz[dq]--;return ;}
if(!ch[dq][0])
{
int a=ch[dq][1];
tree[D].root=a;
fa[a]=0;return ;
}
if(!ch[dq][1])
{
int a=ch[dq][0];
tree[D].root=a;
fa[a]=0;return ;
}
d=key[dq];
pre=-inf;f_pre(dq);Splay(t1);
int a=ch[dq][1];
S.push(dq);
tree[D].root=t1;fa[t1]=0;ch[t1][1]=a;
fa[a]=t1;up(t1);
}
void change(int dq)//3
{
if(tree[dq].l==pos&&tree[dq].r==pos)
{
key[tree[dq].root]=X;
return ;
}
if(tree[dq].l<=pos&&tree[dq].r>=pos)
{
D=dq;Find(tree[dq].root,a[pos]);
del();insert(X,tree[dq].root,0);
}
int mid=(tree[dq].l+tree[dq].r)>>1;
if(mid>=pos)change(dq<<1);
else change(dq<<1|1);
}
//===============================================
int K;
int ask()
{
int l=0,r=1e8;
while(true)
{
int ans=(l+r)>>1;
X=ans;
if(f_n_r(1)+1<=K)
l=ans;
else r=ans;
if(r-l==1)return l;
}
}
int main()
{
// freopen("input8.in","r",stdin);
// freopen("ans.txt","w",stdout);
// int SS=GetTickCount();
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
read(a[i]);
build(1,1,n);
int op;
int T=0;
for(int i=1;i<=m;i++)
{
read(op);
if(op==1)
{
read(L);read(R);read(X);
int Q=f_n_r(1)+1;
printf("%d\n",Q);
}
if(op==2)
{
read(L);read(R);read(K);
int Q=ask();
printf("%d\n",Q);
}
if(op==3)
{
read(pos);read(X);
change(1);a[pos]=X;
}
if(op==4)
{
read(L);read(R);
pre=-inf;read(d);find_pre(1);
printf("%d\n",pre);
}
if(op==5)
{
read(L);read(R);
nxt=inf;read(d);find_nxt(1);
printf("%d\n",nxt);
}
}
// int TT=GetTickCount();
// cout<<"h "<<TT-SS;
return 0;
}