之前没有注意到只查询上一个,下一个,和本身,一直在想怎么把一个数放到最后面,然后还要合并,还要知道每个数当前在数组中的位置,感觉好像不太可做。。。
然后红太阳 lts 光速切掉这题,告诉我这个条件,就可以直接链表维护
动态链表做过当年斌神出的 CSUOJ 2013 珂朵莉的移动硬盘,这种还挺简单的
然后这题要用字典树离散化,然后字典树0号节点一开始没有清空。。。从1号点开始清空的。。。。
不过反正是无敌的lts教我的,现场没A掉也不遗憾。。。
完了多校排名一场比一场差了,只能签签到了
#include<bits/stdc++.h>
#define maxl 500010
using namespace std;
int n,m,tot,nn,cnt;
int tr[maxl*11][11],num[maxl*11];
int nxt[maxl],pre[maxl],val[maxl];
struct qu
{
int op,s,v;
}q[maxl];
char s[11];
bool in[maxl];
inline int insert(char s[])
{
int len=strlen(s),u=0,c;
for(int i=0;i<len;i++)
{
c=s[i]-'0';
if(tr[u][c]==0)
tr[u][c]=++tot;
u=tr[u][c];
}
if(num[u]==0)
num[u]=++cnt;
return num[u];
}
inline void prework()
{
scanf("%d%d",&n,&m);
for(int i=0;i<=tot;i++)
{
num[i]=0;
memset(tr[i],0,sizeof(tr[i]));
}
tot=0;cnt=0;
for(int i=1;i<=n;i++)
{
scanf("%d%s%d",&q[i].op,s,&q[i].v);
q[i].s=insert(s);
}
}
inline void mainwork()
{
for(int i=1;i<=cnt;i++)
nxt[i]=0,pre[i]=0,in[i]=false,val[i]=0;
int head=0,tail=0;int ans,sz=0,l,r;
for(int i=1;i<=n;i++)
{
ans=0;
if(q[i].op==0)
{
if(!in[q[i].s])
{
in[q[i].s]=true;
if(head==0)
{
tail=head=q[i].s;
pre[q[i].s]=nxt[q[i].s]=0;
val[q[i].s]=q[i].v;
sz++;
}
else
{
sz++;val[q[i].s]=q[i].v;
in[q[i].s]=true;
pre[q[i].s]=tail;nxt[q[i].s]=0;
nxt[tail]=q[i].s;
tail=q[i].s;
}
}
else
{
if(sz>1 && tail!=q[i].s)
{
l=pre[q[i].s];r=nxt[q[i].s];
if(l>0)
nxt[l]=r;
if(r>0)
pre[r]=l;
if(q[i].s==head)
head=r,pre[r]=0;
nxt[tail]=q[i].s;
nxt[q[i].s]=0;
pre[q[i].s]=tail;
tail=q[i].s;
}
}
if(sz>m)
{
sz--;
in[head]=false;val[head]=0;
r=nxt[head];
pre[head]=0;nxt[head]=0;
pre[r]=0;
head=r;
}
ans=val[q[i].s];
printf("%d\n",ans);
}
else
{
ans=-100;
if(in[q[i].s])
{
if(q[i].v==1)
{
if(nxt[q[i].s]>0 && in[nxt[q[i].s]])
ans=val[nxt[q[i].s]];
}
else if(q[i].v==-1)
{
if(pre[q[i].s]>0 && in[pre[q[i].s]])
ans=val[pre[q[i].s]];
}
else
ans=val[q[i].s];
}
if(ans==-100)
puts("Invalid");
else
printf("%d\n",ans);
}
}
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
}
return 0;
}