社区讨论
求各位大爷帮我看看到底哪里写挂了……
P3988[SHOI2013] 发牌参与者 12已保存回复 19
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 19 条
- 当前快照
- 1 份
- 快照标识符
- @mi6ud5cq
- 此快照首次捕获于
- 2025/11/20 10:58 4 个月前
- 此快照最后确认于
- 2025/11/20 14:35 4 个月前
本机数据都能AC不过极限数据要1.5s……splay板子题……QAQ我明明觉得我常数不大的啊
CPP#include<iostream>
#include<cstdio>
#define N (700000+1000)
using namespace std;
int n,x,Root,Father[N],Son[N][2],Size[N];
void Update(int x){Size[x]=1+Size[Son[x][0]]+Size[Son[x][1]];}
int Get(int x){return Son[Father[x]][1]==x;}
void Build(int fa,int l,int r)
{
if (l>r) return;
if (l==r) Size[l]=1;
int mid=(l+r)>>1;
Build(mid,l,mid-1);
Build(mid,mid+1,r);
Father[mid]=fa; Son[fa][mid>fa]=mid;
Update(mid);
}
void Rotate(int x)
{
int wh=Get(x);
int fa=Father[x],fafa=Father[fa];
if (fafa) Son[fafa][Son[fafa][1]==fa]=x;
Father[fa]=x; Son[fa][wh]=Son[x][wh^1];
Father[x]=fafa; Son[x][wh^1]=fa;
if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
Update(fa); Update(x);
}
void Splay(int x,int tar)
{
for (int fa; (fa=Father[x])!=tar; Rotate(x))
if (Father[fa]!=tar)
Rotate(Get(fa)==Get(x)?fa:x);
if (!tar) Root=x;
}
int Findkth(int x)
{
int now=Root;
while (1)
if (Size[Son[now][0]]>=x) now=Son[now][0];
else
{
x-=Size[Son[now][0]];
if (x==1){/*Splay(now,0);*/ return now;}
x--; now=Son[now][1];
}
}
int Split(int l,int r)
{
int x=Findkth(l);
int y=Findkth(r+2);
Splay(x,0); Splay(y,x);
return Son[y][0];
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d",&n);
Build(0,1,n+2);
Root=(n+3)>>1;
for (int i=1; i<=n; ++i)
{
scanf("%d",&x); x%=n-i+1;
if (x)
{
int now=Split(1,x);
Son[Father[now]][Son[Father[now]][1]==now]=0;
Father[now]=0;
int fa=Split(n-i+1-x,n-i+1-x);
Son[fa][1]=now; Father[now]=fa;
Splay(now,0);
}
int now=Split(1,1); printf("%d\n",now-1);
Son[Father[now]][0]=0;
Father[now]=0; Update(Son[Root][1]);
}
}
回复
共 19 条回复,欢迎继续交流。
正在加载回复...