Chino的数列

题解:

一道练代码能力的题目。。

首先很显然他是一道平衡树裸题

第5个操作是势能分析维护最大值最小值就可以了

另外设置虚点和noip2017队列那题一样(不过我只写过线段树)

具体细节:

1.内存池,要直接判断(!x) 因为可能进去就是0

2.输出的时候有重复的要都输出

3.search的时候要down

4.为了简单我写的down是更新自己的,而这个标记会对updata产生影响,所以updata的时候要down两个儿子

5.splay虚点变变三个点要判断点数,分三种情况 1个点,2个点,>2个点

这个洛谷评测是什么鬼。。数据测出来是对的显示wa

另外本题也可以用分块做。。以后写下试试

代码:

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define me(x) memset(x,0,sizeof(x))
#define ll long long
const int INF=1e9;
const int N=4e6;
queue<int> q;
int s[N],count2[N],count3[N],data[N],maxa[N],mina[N],rs[N],ls[N],lazy[N],fa[N],root;
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
int cnt,minxx=INF;
struct phs{
IL void down(rint x)
{
if (lazy[x]==INF) return;
maxa[x]=mina[x]=data[x]=lazy[x];
if (ls[x]) lazy[ls[x]]=lazy[x];
if (rs[x]) lazy[rs[x]]=lazy[x];
lazy[x]=INF;
}
IL void updata(rint x)
{
rint l=ls[x],r=rs[x],tmp=data[x];
down(l); down(r);
count2[x]=count2[l]+count2[r]+count3[x];
maxa[x]=max(tmp,max(maxa[l],maxa[r]));
mina[x]=min(tmp,min(mina[l],mina[r]));
}
IL void rotate(int x,int y)
{
int fa1=fa[x];
if (y==)
{
if (ls[x]) fa[ls[x]]=fa1;
rs[fa1]=ls[x];
} else
{
if (rs[x]) fa[rs[x]]=fa1;
ls[fa1]=rs[x];
}
fa[x]=fa[fa1];
if(fa[fa1])
{
if (ls[fa[fa1]]==fa1) ls[fa[fa1]]=x;
else rs[fa[fa1]]=x;
}
fa[fa1]=x;
if (y==) ls[x]=fa1; else rs[x]=fa1;
updata(fa1);
updata(x);
}
void dfs(int x)
{
if (fa[x]) dfs(fa[x]);
down(x);
}
IL void splay(int x,int goal)
{
dfs(x);
int fa1=fa[x];
while (fa1!=goal)
{
if (fa[fa1]==goal)
{
if (x==ls[fa1]) rotate(x,); else rotate(x,);
} else
if (fa1==ls[fa[fa1]])
if (x==ls[fa1])
rotate(fa1,),rotate(x,);
else rotate(x,),rotate(x,);
else
if (x==rs[fa1])
rotate(fa1,),rotate(x,);
else rotate(x,),rotate(x,);
fa1=fa[x];
}
if (goal==) root=x;
}
IL int search(rint k)
{
rint x=root;
while (x)
{
down(x);
if (s[x])
{
rint l=ls[x],r=rs[x];
rint tmp=count3[x];
count3[x]=;
rint now=ls[x]=q.front(); q.pop();
fa[now]=x;
if ((count3[ls[x]]=tmp/)!=) s[now]=;
ls[now]=l; fa[l]=now; data[now]=data[x]; updata(now);
if (tmp>)
{
now=rs[x]=q.front(); q.pop(); data[rs[x]]=data[x];
fa[now]=x;
if ((count3[now]=tmp-(tmp/)-)!=) s[now]=;
rs[now]=r; fa[r]=now; updata(now);
}
down(x);
s[x]=;
}
if (count2[ls[x]]+==k) return(x);
if (count2[ls[x]]+<k) k-=count2[ls[x]]+,x=rs[x];
else x=ls[x];
}
}
void dfs2(int x)
{
if (!x) return;
cnt++;
q.push(x);
dfs2(ls[x]);
dfs2(rs[x]);
ls[x]=rs[x]=count2[x]=s[x]=data[x]=fa[x]=maxa[x]=mina[x]=;
count3[x]=;
lazy[x]=INF;
}
IL void split(int x,int y)
{
splay(x,);
splay(y,x);
}
IL void cl(int x)
{
down(x);
int k1=sqrt(maxa[x]); int k2=sqrt(mina[x]);
if (k1==k2)
{
lazy[x]=k1; down(x);
return;
}
data[x]=sqrt(data[x]);
if (ls[x]) cl(ls[x]);
if (rs[x]) cl(rs[x]);
updata(x);
}
IL void ycl()
{
root=; rs[]=; fa[]=; count2[]=; count2[]=;
}
IL void ou(int x)
{
down(x);
if (ls[x]) ou(ls[x]);
if (x!=&&x!=)
rep(i,,count3[x])
printf("%d ",data[x]);
if (rs[x]) ou(rs[x]);
}
}S;
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
ios::sync_with_stdio(false);
int m;
cin>>m;
maxa[]=-INF; mina[]=INF;
int len=;
rep(i,,N-) q.push(i);
rep(i,,N-) lazy[i]=INF,count3[i]=;
S.ycl();
rep(i,,m)
{
minxx=min(minxx,q.size());
int x,y,z,k;
cin>>k;
if (k==)
{
cin>>x>>y;
rint now=S.search(len+);
S.splay(,);
S.splay(now,);
rint now2=rs[now]=q.front(); q.pop();
count3[now2]=x; data[now2]=y; fa[now2]=now;
if (x!=) s[now2]=;
S.splay(now2,);
len+=x;
}
if (k==)
{
int x;
cin>>x;
len-=x;
x=S.search(x+);
S.split(,x);
// S.dfs2(ls[x]);
ls[x]=;
S.splay(x,);
}
if (k==)
{
int kk;
cin>>x>>y>>z>>kk;
rint t=y-x+;
rint ans=;
while(z)
{
if (z&) ans=(1ll*ans*t)%kk;
t=(1ll*t*t)%kk;
z>>=;
}
int l=S.search(x);
int r=S.search(y+);
S.split(l,r);
lazy[ls[r]]=ans;
S.splay(ls[r],);
}
if (k==)
{
int x,y;
cin>>x>>y;
//cout<<x<<" "<<y<<endl;
len-=y-x;
x=S.search(x),y=S.search(y+);
S.split(x,y);
S.down(ls[y]);
int now=ls[y];
int mm=maxa[now];
// S.dfs2(ls[now]); S.dfs2(rs[now]);
ls[now]=rs[now]=; lazy[now]=INF; count3[now]=; s[now]=;
data[now]=mm; S.splay(now,);
printf("%d\n",mm);
}
if (k==)
{
cin>>x>>y;
x=S.search(x),y=S.search(y+);
S.split(x,y);
int now=ls[y];
S.cl(now);
}
}
S.ou(root);
// printf("\n%d\n%d",cnt,minxx);
return ;
}
上一篇:第二十次CCF计算机软件能力认证 星际旅行 (计算几何)


下一篇:常用的Dos命令