链接
做法一
可持久化栈,其实就是一棵树。
要维护每个结点的深度、每个结点的父节点、当前的根节点,之前的根节点。
还要维护当前字符串,以及当前字符串长度。写了半天才调过。
写完这个题我开始怀疑:这真的是两星的题???
于是想了半天我突然开窍了,这题直接暴力好像就行了嘛
做法二
记录每次操作是插入了什么字符串,或者删除了什么字符串。
因为每个字符最多插入一次,删除一次,所以时间复杂度是线性的。
撤销的时候,直接暴力撤销就行了。
代码一
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define maxe 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define de(x) cerr<<#x<<" = "<<x<<endl
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
char nd[maxn], s[maxn], now[maxn];
ll top[maxn], fa[maxn], dep[maxn];
int main()
{
ll i, top_tot, q, nd_tot, len;
while(~scanf("%lld",&q))
{
ll i, j;
top_tot = nd_tot = len = 0;
rep(i,1,q)
{
ll type=read();
if(type==1)
{
scanf("%s", s);
ll n = strlen(s);
ll pre = top[top_tot];
rep(j,0,n-1)
{
fa[nd_tot+1] = pre;
nd_tot ++;
nd[nd_tot] = s[j];
now[++len] = s[j];
dep[nd_tot] = dep[pre] +1;
pre = nd_tot;
}
top_tot++;
top[top_tot] = nd_tot;
rep(j,0,n-1)s[j]=0;
}
else if(type==2)
{
top_tot++, top[top_tot]=top[top_tot-1];
ll k=read();
while(k--)top[top_tot] = fa[top[top_tot]], len--;
}
else if(type==3)
{
ll k=read();
putchar(now[k]); putchar(10);
}
else
{
top_tot --;
if(dep[top[top_tot]] < len)len = dep[top[top_tot]];
else
{
ll t=dep[top[top_tot]];
for(j=top[top_tot];dep[j]>len;j=fa[j])now[t--]=nd[j];
len = dep[top[top_tot]];
}
}
}
}
return 0;
}
代码二
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 2000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define de(x) cerr<<#x<<" = "<<x<<endl
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
ll pos[maxn], len[maxn], slen, tp[maxn];
char S[maxn], nows[maxn], s[maxn];
int main()
{
ll i, now, q;
len[0]=1;
while(~scanf("%lld",&q))
{
ll i, j;
now = 0, slen = 0;
rep(i,1,q)
{
ll type=read();
if(type==1)
{
scanf("%s",s);
ll n = strlen(s);
now++;
tp[now] = 1;
pos[now] = pos[now-1]+len[now-1];
len[now] = 0;
rep(j,0,n-1)
{
S[pos[now]+(len[now]++)] = s[j];
nows[++slen]=s[j];
s[j]=0;
}
}
else if(type==2)
{
ll k=read();
now++;
tp[now] = 2;
pos[now] = pos[now-1]+len[now-1];
len[now] = 0;
rep(j,slen-k+1,slen)
S[pos[now]+(len[now]++)] = nows[j];
slen -= k;
}
else if(type==3)
{
ll k=read();
putchar(nows[k]); putchar(10);
}
else
{
if(tp[now]==1)
{
rep(j,1,len[now])slen--;
}
else
{
rep(j,0,len[now]-1)nows[++slen]=S[pos[now]+j];
}
now--;
}
// de(S+1);
}
}
return 0;
}