QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#220312 | #6556. Text Editor | ExplodingKonjac | 0 | 1ms | 5884kb | C++20 | 9.0kb | 2023-10-20 07:12:40 | 2023-10-20 07:12:41 |
answer
#include <bits/stdc++.h>
using namespace std;
#define OPENIOBUF
namespace FastIO
{
class FastIOBase
{
protected:
#ifdef OPENIOBUF
static const int BUFSIZE=1<<16;
char buf[BUFSIZE+1];
int buf_p=0;
#endif
FILE *target;
FastIOBase(FILE *f): target(f){}
~FastIOBase()=default;
public:
#ifdef OPENIOBUF
virtual void flush()=0;
#endif
};
class FastOutput final: public FastIOBase
{
private:
void __putc(char x)
{
#ifdef OPENIOBUF
if(buf[buf_p++]=x,buf_p==BUFSIZE) flush();
#else
putc(x,target);
#endif
}
template<typename T>
void __write(T x)
{
char stk[numeric_limits<T>::digits10+1],*top=stk;
if(x<0) return __putc('-'),__write(-x);
do *(top++)=x%10,x/=10; while(x);
for(;top!=stk;__putc(*(--top)+'0'));
}
public:
FastOutput(FILE *f=stdout): FastIOBase(f) {}
#ifdef OPENIOBUF
~FastOutput() { flush(); }
void flush() { fwrite(buf,1,buf_p,target),buf_p=0; }
#endif
FastOutput &operator <<(char x)
{ return __putc(x),*this; }
FastOutput &operator <<(const char *s)
{ for(;*s;__putc(*(s++)));return *this; }
FastOutput &operator <<(const std::string &s)
{ return (*this)<<s.c_str(); }
template<typename T>
std::enable_if_t<std::is_integral<T>::value,FastOutput&> operator <<(const T &x)
{ return __write(x),*this; }
template<typename ...T>
void writesp(const T &...x)
{ std::initializer_list<int>{(this->operator<<(x),__putc(' '),0)...}; }
template<typename ...T>
void writeln(const T &...x)
{ std::initializer_list<int>{(this->operator<<(x),__putc('\n'),0)...}; }
template<typename Iter>
void writesp(Iter begin,Iter end)
{ while(begin!=end) (*this)<<*(begin++)<<' '; }
template<typename Iter>
void writeln(Iter begin,Iter end)
{ while(begin!=end) (*this)<<*(begin++)<<'\n'; }
}qout;
class FastInput final: public FastIOBase
{
private:
bool __eof;
public:
FastInput(FILE *f=stdin): FastIOBase(f),__eof(false)
#ifdef OPENIOBUF
{ buf_p=BUFSIZE; }
void flush() { buf[fread(buf,1,BUFSIZE,target)]=EOF,buf_p=0; }
bool eof()const { return buf[buf_p]==EOF; }
#else
{}
bool eof()const { return feof(target); }
#endif
char get()
{
if(__eof) return EOF;
#ifdef OPENIOBUF
if(buf_p==BUFSIZE) flush();
char ch=buf[buf_p++];
#else
char ch=getc(target);
#endif
return ~ch?ch:(__eof=true,EOF);
}
void unget(char c)
{
__eof=false;
#ifdef OPENIOBUF
buf[--buf_p]=c;
#else
ungetc(c,target);
#endif
}
explicit operator bool()const { return !__eof; }
FastInput &operator >>(char &x)
{ while(isspace(x=get()));return *this; }
template<typename T>
std::enable_if_t<std::is_integral<T>::value,FastInput&> operator >>(T &x)
{
char ch,sym=0;x=0;
while(isspace(ch=get()));
if(__eof) return *this;
if(ch=='-') sym=1,ch=get();
for(;isdigit(ch);x=(x<<1)+(x<<3)+(ch^48),ch=get());
return unget(ch),sym?x=-x:x,*this;
}
FastInput &operator >>(char *s)
{
while(isspace(*s=get()));
if(__eof) return *this;
for(;!isspace(*s) && !__eof;*(++s)=get());
return unget(*s),*s='\0',*this;
}
FastInput &operator >>(std::string &s)
{
char str_buf[(1<<8)+1]={0},*p=str_buf;
char *const buf_end=str_buf+(1<<8);
while(isspace(*p=get()));
if(__eof) return *this;
for(s.clear(),p++;;p=str_buf)
{
for(;p!=buf_end && !isspace(*p=get()) && !__eof;p++);
if(p!=buf_end) break;
s.append(str_buf);
}
unget(*p),*p='\0',s.append(str_buf);
return *this;
}
template<typename ...T>
void read(T &...x)
{ std::initializer_list<int>{(this->operator>>(x),0)...}; }
template<typename Iter>
void read(Iter begin,Iter end)
{ while(begin!=end) (*this)>>*(begin++); }
}qin;
} // namespace FastIO
using FastIO::qin,FastIO::qout;
using LL=long long;
using LD=long double;
using UI=unsigned int;
using ULL=unsigned long long;
#ifndef DADALZY
#define FILEIO(file) freopen(file".in","r",stdin),freopen(file".out","w",stdout)
#define LOG(...) void()
#else
#define FILEIO(file)
#define LOG(...) fprintf(stderr,__VA_ARGS__)
#endif
int n;
class Serializer: public stringstream
{
private:
static constexpr int MIN=33,MAX=126,B=MAX-MIN+1;
public:
void putChar(char c)
{
this->put(c);
}
void putInt32(uint32_t x)
{
constexpr int W=5;
char res[W];
for(int i=1;i<=W;i++)
res[W-i]=x%B+MIN,x/=B;
this->write(res,W);
}
void putInt64(uint64_t x)
{
constexpr int W=10;
char res[W];
for(int i=1;i<=W;i++)
res[W-i]=x%B+MIN,x/=B;
this->write(res,W);
}
char getChar()
{
return this->get();
}
uint32_t getInt32()
{
constexpr int W=5;
uint32_t res=0;
for(int i=0;i<W;i++)
res=res*B+this->get()-MIN;
return res;
}
uint64_t getInt64()
{
constexpr int W=10;
uint64_t res=0;
for(int i=0;i<W;i++)
res=res*B+this->get()-MIN;
return res;
}
}stream;
mt19937 mt_rnd(19260817);
struct TreapNode{ int l,r,sz0,lc,rc;LL siz; }t[10000005];
int tot;
inline int newNode(int l,int r)
{ return assert(tot<10000000),t[++tot]=TreapNode{l,r,1,0,0,1},tot; }
inline int copyNode(int i)
{ return assert(tot<10000000),t[++tot]=t[i],tot; }
inline void pushup(int i)
{
t[i].sz0=t[t[i].lc].sz0+t[t[i].rc].sz0+1;
t[i].siz=t[t[i].lc].siz+t[t[i].rc].siz+(t[i].r-t[i].l+1);
}
void split(int i,LL k,int &x,int &y)
{
if(!i) return x=y=0,void();
LL sz=t[t[i].lc].siz,len=t[i].r-t[i].l+1;
if(k>=sz+len)
x=copyNode(i),split(t[i].rc,k-sz-len,t[x].rc,y),pushup(x);
else if(k<=sz)
y=copyNode(i),split(t[i].lc,k,x,t[y].lc),pushup(y);
else
{
x=copyNode(i),y=copyNode(i);
t[x].rc=0,t[x].r=t[x].l+(k-sz)-1;
t[y].lc=0,t[y].l=t[y].r-(sz+len-k)+1;
pushup(x),pushup(y);
}
}
int merge(int x,int y,bool cp=true)
{
if(!x || !y) return x|y;
bool fl=(mt_rnd()%(t[x].sz0+t[y].sz0)<t[x].sz0);
int z=(fl?x:y);
if(cp) z=copyNode(z);
if(fl) t[z].rc=merge(t[z].rc,y,cp);
else t[z].lc=merge(x,t[z].lc,cp);
return pushup(z),z;
}
string S;
int clip,cur,mxc,top,mxt,rt[100005],stk[100005];
void dump(int i,string &res)
{
if(!i) return;
dump(t[i].lc,res);
res.append(S.substr(t[i].l,t[i].r-t[i].l+1));
dump(t[i].rc,res);
}
inline void update()
{
stk[mxt=++top]=++mxc;
rt[mxc]=rt[cur],cur=mxc;
}
inline void insert(LL p,LL l,LL r)
{
int x,y,z;
split(rt[cur],p,x,z);
y=newNode(l,r);
rt[cur]=merge(merge(x,y),z);
}
inline string print(LL l,LL r)
{
int x,y,z;
split(rt[cur],r,x,z),split(x,l-1,x,y);
string res;
dump(y,res);
rt[cur]=merge(merge(x,y),z);
return res;
}
inline void erase(LL l,LL r)
{
int x,y,z;
split(rt[cur],r,x,z),split(x,l-1,x,y);
rt[cur]=merge(x,z);
}
inline void copy(LL l,LL r)
{
int x,y,z;
split(rt[cur],r,x,z),split(x,l-1,x,y);
clip=y;
rt[cur]=merge(merge(x,y),z);
}
inline void cut(LL l,LL r)
{
int x,y,z;
split(rt[cur],r,x,z),split(x,l-1,x,y);
clip=y;
rt[cur]=merge(x,z);
}
inline void paste(LL p)
{
int x,y;
split(rt[cur],p,x,y);
rt[cur]=merge(merge(x,clip),y);
}
inline void serialize()
{
stream.putInt32(S.size());
stream.write(S.data(),S.size());
int sz=0;
auto getsz=[&](auto &self,int i) {
if(!i) return;
sz++;
self(self,t[i].lc);
self(self,t[i].rc);
};
auto dump=[&](auto &self,int i) {
if(!i) return;
self(self,t[i].lc);
stream.putInt32(t[i].l);
stream.putInt32(t[i].r);
self(self,t[i].rc);
};
getsz(getsz,rt[cur]);
stream.putInt32(sz);
dump(dump,rt[cur]);
}
inline void deserialize()
{
int sz=stream.getInt32();
S.resize(sz,0),stream.read(S.data(),sz);
sz=stream.getInt32();
rt[cur]=0;
for(int i=1;i<=sz;i++)
{
int l=stream.getInt32(),
r=stream.getInt32();
rt[cur]=merge(rt[cur],newNode(l,r),false);
}
}
void debug()
{
#ifdef DADALZY
string str;
dump(rt[cur],str);
LOG("[debug] file: %s\n",str.c_str());
str.clear();
dump(clip,str);
LOG("[debug] clipboard: %s\n",str.c_str());
#endif
}
int main()
{
qin>>n;
string op,str;
while(n--)
{
int p,l,r;
qin>>op;
if(op=="insert")
{
qin>>p>>str;
S.append(str);
update();
l=S.size()-str.size(),r=S.size()-1;
insert(p,l,r);
}
else if(op=="print")
{
qin>>l>>r,l++;
str=print(l,r);
qout<<str<<'\n';
}
else if(op=="erase")
{
qin>>l>>r,l++;
update();
erase(l,r);
}
else if(op=="copy")
{
qin>>l>>r,l++;
copy(l,r);
}
else if(op=="cut")
{
qin>>l>>r,l++;
update();
cut(l,r);
}
else if(op=="paste")
{
qin>>p;
update();
paste(p);
}
else if(op=="undo")
{
if(top>0) cur=stk[--top];
}
else if(op=="redo")
{
if(top<mxt) cur=stk[++top];
}
else if(op=="serialize")
{
serialize();
qout<<stream.str()<<'\n';
}
else if(op=="deserialize")
{
qin>>str,stream.str(str);
update();
deserialize();
}
else qout<<"🐸\n";
debug();
}
return 0;
}
/*
first run:
17
insert 0 abcdef
print 0 6
erase 4 5
print 0 5
copy 0 3
paste 1
print 0 8
cut 2 4
print 0 6
undo
print 0 8
paste 6
print 0 10
redo
redo
print 0 10
serialize
second run:
2
deserialize !!!!'abcdef!!!!'!!!!!!!!!!!!!!!!!!!#!!!!"!!!!#!!!!"!!!!#!!!!$!!!!$!!!!&!!!!&
print 0 10
*/
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 5560kb
First Run Input
17 insert 0 abcdef print 0 6 erase 4 5 print 0 5 copy 0 3 paste 1 print 0 8 cut 2 4 print 0 6 undo print 0 8 paste 6 print 0 10 redo redo print 0 10 serialize
First Run Output
abcdef abcdf aabcbcdf aabcdf aabcbcdf aabcbcbcdf aabcbcbcdf !!!!'abcdef!!!!'!!!!!!!!!!!!!!!!!!!#!!!!"!!!!#!!!!"!!!!#!!!!$!!!!$!!!!&!!!!&
Second Run Input
2 deserialize !!!!'abcdef!!!!'!!!!!!!!!!!!!!!!!!!#!!!!"!!!!#!!!!"!!!!#!!!!$!!!!$!!!!&!!!!& print 0 10
Second Run Output
aabcbcbcdf
result:
ok stage 2 is ok!
Test #2:
score: 100
Accepted
time: 0ms
memory: 3644kb
First Run Input
1 serialize
First Run Output
!!!!!!!!!!
Second Run Input
1 deserialize !!!!!!!!!!
Second Run Output
result:
ok stage 2 is ok!
Test #3:
score: 100
Accepted
time: 0ms
memory: 3628kb
First Run Input
31 undo redo redo undo undo undo redo undo redo undo undo undo undo undo redo redo undo undo redo undo redo redo redo undo undo undo redo undo redo redo serialize
First Run Output
!!!!!!!!!!
Second Run Input
31 deserialize !!!!!!!!!! redo undo redo redo redo redo redo undo undo undo redo redo undo redo undo redo undo redo undo redo undo undo undo undo redo redo redo undo redo redo
Second Run Output
result:
ok stage 2 is ok!
Test #4:
score: 100
Accepted
time: 1ms
memory: 5624kb
First Run Input
31 undo redo redo undo undo redo redo redo undo undo undo redo redo undo redo undo redo undo redo redo redo undo redo undo redo redo undo undo redo undo serialize
First Run Output
!!!!!!!!!!
Second Run Input
31 deserialize !!!!!!!!!! undo redo undo redo redo redo undo undo undo redo undo redo undo redo undo undo redo undo undo undo undo undo undo redo undo redo undo redo redo redo
Second Run Output
result:
ok stage 2 is ok!
Test #5:
score: 100
Accepted
time: 1ms
memory: 5884kb
First Run Input
31 undo undo undo redo redo redo redo undo undo redo redo undo undo undo redo redo redo redo undo redo redo undo undo undo redo undo undo undo undo redo serialize
First Run Output
!!!!!!!!!!
Second Run Input
31 deserialize !!!!!!!!!! redo redo undo undo undo redo redo redo redo redo redo redo redo redo undo undo redo undo redo redo undo redo redo redo redo redo redo undo redo undo
Second Run Output
result:
ok stage 2 is ok!
Test #6:
score: 0
Wrong Answer on the first run
First Run Input
1001 insert 0 u]^rGH]V+A3/VCu}4-dod,hyG&]WkL1)rg$W4\W0XL7sfyA[GNpfX2rx8Sc6$fmzW&x3E//Q0M\7=?Io7mupWV9Y4z6aY4E9ia$S{1KfioW29lST';?emw,Upk.b`^tl.O^btxvAx>:=&rC@6k`[GQCv;s[myKiSV1tp!Z)bj: copy 0 170 paste 170 copy 0 340 paste 340 cut 415 652 copy 0 443 paste 443 cut 282 500 erase 0 576 copy 0 92 paste ...
First Run Output
/VCu}4-dod,hyG&]WkL1)rg)bj:/VCu}4-dyKlPm}+uRG&]WkL1)rg)bj:/V)bj:/VCu})bj:/)rg)bj:/VCG&]WkL1)rg)bj:/VCu}4-dyKlPm}+uRG&]WkL1)rg)bj:/V) /VCu}4/VCu}4 4/VCu}4/VCu}4/VCu}4/VCu}4/VCu}4/4/VCu}4/VCu}4/VCu}4/VCu}4/VCu}4/VCu}4/VCu}4/VCu}4/VCu}4/VCu} u}4/VCu}/VCu}4/VCu/V x+v6CNGx>Z6N<;P)ur4\-KO&E7g*YI|g-y&bfL...
Second Run Input
Second Run Output
result:
wrong answer wrong answer on query 4 (in the first run)