QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#622917#9425. Generated Stringaqx_AK_xyfWA 24ms235584kbC++148.0kb2024-10-09 08:30:212024-10-09 08:30:24

Judging History

你现在查看的是最新测评结果

  • [2024-10-14 17:49:05]
  • hack成功,自动添加数据
  • (/hack/995)
  • [2024-10-09 08:30:24]
  • 评测
  • 测评结果:WA
  • 用时:24ms
  • 内存:235584kb
  • [2024-10-09 08:30:21]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
// #define int long long
int inf=0x3f3f3f3f;
const int mod=998244353;
const int N=2e5+5,M=2.4e6+5;
int n,m,q,Q=2.4e6,ans[N];
string s;
int lg2[N];
struct SufArray{
    int m,sa[N],rk[N],_rk[N];
    basic_string<int>p[N];
    int h[N],st[N][18];
    void init(){
        for(int i=1;i<=n;i++)sa[i]=i;
        stable_sort(sa+1,sa+n+1,[](int x,int y){return s[x]<s[y];});
        for(int i=1;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(s[sa[i]]>s[sa[i-1]]);
        for(int i=0;i<17;i++){
            m=0;
            int w=(1<<i);
            for(int j=1;j<=n;j++)p[j].clear();
            for(int j=1;j<=n;j++)
                if(sa[j]+w>n)p[rk[sa[j]]].push_back(sa[j]);
            for(int j=1;j<=n;j++)
                if(sa[j]>w)p[rk[sa[j]-w]].push_back(sa[j]-w);
            int now=0;
            for(int j=1;j<=n;j++){
                int lst=-1;
                for(int k:p[j]){
                    sa[++m]=k;
                    int xin=(k+w>n?0:rk[k+w]);
                    if(xin>lst)now++,lst=xin;
                    _rk[k]=now;
                }
            }
            memcpy(rk,_rk,sizeof(rk));
        }
        for(int i=1,H=0;i<=n;i++){
            if(rk[i]==1)continue;
            if(H)H--;
            while(s[i+H]==s[sa[rk[i]-1]+H])H++;
            h[rk[i]]=H;
        }
        // for(int i=1;i<=n;i++)cout<<sa[i]<<' ';
        // cout<<endl;
        // for(int i=1;i<=n;i++)cout<<h[i]<<' ';
        // cout<<endl;
        for(int i=1;i<=n;i++)st[i][0]=h[i];
        for(int i=0;i<17;i++)
            for(int j=1;j<=n;j++){
                if(j+(1<<i)>n)st[j][i+1]=st[j][i];
                else st[j][i+1]=min(st[j][i],st[j+(1<<i)][i]);
            }
    }
    int LCP(int x,int y){
        if(x==y)return n-x+1;
        int l=rk[x],r=rk[y];
        if(l>r)swap(l,r);
        l++;
        int len=lg2[r-l+1];
        return min(st[l][len],st[r-(1<<len)+1][len]);
    }
}SA[2];
struct seg{int l,r;};
struct query{
    int op;
    basic_string<seg>a;
}e[2][N];
int L[N][2],R[N][2];
struct Trie{
    int id,rt,tot;
    int f[M],to[M][26],sz[M];
    seg ch[M][26];
    basic_string<int>ed[M];
    int top,rec[M];
    int now_dfn,dfn[M],dfr[M];
    struct INS{
        int p,sz;
        bool operator<(const INS &y)const{
            return sz>y.sz;
        }
    };
    priority_queue<INS>que;
    void push_up(int p){
        sz[p]=1;
        for(int i=0;i<f[p];i++)sz[p]+=sz[to[p][i]];
    }
    int merge(int p1,int p2){
        // if(id==0)cerr<<p1<<' '<<p2<<endl;
        if(ed[p1].size()>ed[p2].size())swap(p1,p2);
        for(int i:ed[p1])ed[p2]+=i;
        for(int i=0;i<f[p1];i++){
            seg z=ch[p1][i];
            bool flag=0;
            for(int j=0;j<f[p2];j++){
                seg y=ch[p2][j];
                int lcp=SA[id].LCP(z.l,y.l);
                if(!lcp)continue;
                flag=1;
                int len1=z.r-z.l+1,len2=y.r-y.l+1;
                lcp=min(lcp,min(len1,len2));
                if(lcp==len1&&lcp==len2){to[p2][j]=merge(to[p1][i],to[p2][j]);break;}
                else if(lcp==len1){
                    int pp=(top?rec[top--]:++tot),_p=to[p2][j];
                    ch[p2][j]=z,to[p2][j]=pp;
                    ch[pp][f[pp]]=seg{y.l+lcp,y.r},to[pp][f[pp]]=_p,f[pp]++;
                    to[p2][j]=merge(to[p1][i],to[p2][j]);
                    break;
                }
                else if(lcp==len2){
                    int pp=(top?rec[top--]:++tot),_p=to[p1][i];
                    ch[p1][i]=y,to[p1][i]=pp;
                    ch[pp][f[pp]]=seg{z.l+lcp,z.r},to[pp][f[pp]]=_p,f[pp]++;
                    to[p2][j]=merge(to[p1][i],to[p2][j]);
                    break;
                }
                else{
                    int pp=(top?rec[top--]:++tot),_p=to[p2][j];
                    ch[p2][j]=seg{y.l,y.l+lcp-1},to[p2][j]=pp;
                    ch[pp][f[pp]]=seg{z.l+lcp,z.r},to[pp][f[pp]]=to[p1][i],f[pp]++;
                    ch[pp][f[pp]]=seg{y.l+lcp,y.r},to[pp][f[pp]]=_p,f[pp]++;
                    push_up(pp);
                }
            }
            if(!flag){
                ch[p2][f[p2]]=z,to[p2][f[p2]]=to[p1][i],f[p2]++;
            }
            // if(tot>2.3e6)exit(0);
        }
        push_up(p2);
        rec[++top]=p1,f[p1]=0;
        return p2;
    }
    void ins(){
        for(int i=1;i<=q;i++){
            int m=e[id][i].a.size();
            int p=++tot;
            int pp=p;
            sz[p]=m+1;
            for(int j=0;j<m;j++){
                ch[p][f[p]]=e[id][i].a[j],to[p][f[p]]=++tot,sz[tot]=m-j,f[p]++;
                p=tot;
            }
            ed[p]+=i;
            que.push({pp,sz[pp]});
        }
        while(que.size()>1){
            int p1=que.top().p;que.pop();
            int p2=que.top().p;que.pop();
            p2=merge(p1,p2);
            que.push({p2,sz[p2]});
        }
        rt=que.top().p;
    }
    void dfs(int u){
        dfn[u]=dfr[u]=++now_dfn;
        // if(id==0){
        //     cerr<<u<<": ";
        //     for(int i=0;i<f[u];i++)cerr<<to[u][i]<<' ';
        //     cerr<<endl;
        // }
        for(int i=0;i<f[u];i++)dfs(to[u][i]),dfr[u]=dfr[to[u][i]];
        for(int i:ed[u])L[i][id]=dfn[u],R[i][id]=dfr[u];
    }
}tr[2];
struct nod{int op,val;}g[N];
int d[N],l[N],r[N];
int p[N],_p[N];
int t[M];
int lowbit(int x){return x&-x;}
void add(int x,int k){for(;x<=Q;x+=lowbit(x))t[x]+=k;}
int ask(int x){int ret=0;for(;x;x-=lowbit(x))ret+=t[x];return ret;}
int ask(int l,int r){return ask(r)-ask(l-1);}
void cdq(int L,int R){
    if(L==R)return;
    int mid=(L+R)>>1;
    cdq(L,mid),cdq(mid+1,R);
    int x=L,y=mid+1;
    for(;y<=R;y++){
        if(!g[p[y]].op)continue;
        for(;x<=mid&&d[p[x]]<=d[p[y]];x++)
            if(!g[p[x]].op)add(l[p[x]],g[p[x]].val);
        ans[g[p[y]].op]+=ask(l[p[y]],r[p[y]])*g[p[y]].val;
    }
    for(x--;x>=L;x--)
        if(!g[p[x]].op)add(l[p[x]],-g[p[x]].val);
    x=L,y=mid+1;
    int k=L-1;
    while(x<=mid&&y<=R){
        if(d[p[x]]<=d[p[y]])_p[++k]=p[x],x++;
        else _p[++k]=p[y],y++;
    }
    while(x<=mid)_p[++k]=p[x],x++;
    while(y<=R)_p[++k]=p[y],y++;
    for(int i=L;i<=R;i++)p[i]=_p[i];
}
void solve(){
    cin>>n>>q;
    cin>>s,s=" "+s+" ";
    for(int i=2;i<=n;i++)lg2[i]=lg2[i/2]+1;
    SA[0].init();
    reverse(s.begin(),s.end());
    SA[1].init();
    for(int i=1;i<=q;i++){
        char op;cin>>op;
        if(op=='+'){
            e[0][i].op=e[1][i].op=1;
            int k;cin>>k;
            for(int j=0,l,r;j<k;j++)cin>>l>>r,e[0][i].a+=seg{l,r},e[1][i].a+=seg{n-r+1,n-l+1};
            reverse(e[1][i].a.begin(),e[1][i].a.end());
        }
        if(op=='-'){
            e[0][i].op=-1;
            int id;cin>>id;
            e[0][i].a=e[0][id].a,e[1][i].a=e[1][id].a;
        }
        if(op=='?'){
            e[0][i].op=e[1][i].op=0;
            int k;cin>>k;
            for(int j=0,l,r;j<k;j++)cin>>l>>r,e[0][i].a+=seg{l,r};
            cin>>k;
            for(int j=0,l,r;j<k;j++)cin>>l>>r,e[1][i].a+=seg{n-r+1,n-l+1};
            reverse(e[1][i].a.begin(),e[1][i].a.end());
        }
    }
    tr[0].id=0,tr[1].id=1;
    tr[0].ins(),tr[1].ins();
    tr[0].dfs(tr[0].rt),tr[1].dfs(tr[1].rt);
    for(int i=1;i<=q;i++){
        if(e[0][i].op){
            m++;
            g[m]=nod{0,e[0][i].op};
            d[m]=L[i][0],l[m]=r[m]=L[i][1];
        }
        else{
            m++;
            g[m]=nod{i,1};
            d[m]=R[i][0],l[m]=L[i][1],r[m]=R[i][1];
            m++;
            g[m]=nod{i,-1};
            d[m]=L[i][0]-1,l[m]=L[i][1],r[m]=R[i][1];
        }
    }
    // for(int i=1;i<=m;i++)cerr<<g[i].op<<' '<<g[i].val<<' '<<d[i]<<' '<<l[i]<<' '<<r[i]<<endl;
    for(int i=1;i<=m;i++)p[i]=i;
    cdq(1,m);
    for(int i=1;i<=q;i++)
        if(!e[0][i].op)cout<<ans[i]<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0);
    // freopen("data.in","r",stdin);
    // freopen("data.out","w",stdout);
    int aqx=1;
    while(aqx--)solve();
    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 20ms
memory: 233048kb

input:

8 7
abcaabbc
+ 3 1 3 2 4 3 8
+ 2 1 4 1 8
+ 1 2 4
? 1 5 6 1 7 8
- 3
+ 1 2 5
? 1 2 3 1 5 5

output:

2
1

result:

ok 2 lines

Test #2:

score: -100
Wrong Answer
time: 24ms
memory: 235584kb

input:

5 2000
bbaab
+ 1 3 5
+ 2 5 5 3 5
- 2
? 1 1 3 3 3 3 4 5 2 5
- 1
? 3 1 1 2 4 1 5 1 3 4
? 1 1 2 2 2 4 4 4
? 1 1 5 1 5 5
+ 3 1 2 1 5 1 4
? 2 1 5 1 3 2 1 2 5 5
? 1 3 4 1 4 5
- 9
? 1 1 4 1 2 3
+ 2 1 5 1 2
+ 1 1 4
- 15
- 14
? 2 2 5 2 5 1 3 4
+ 1 2 3
- 19
+ 3 1 4 1 5 4 5
- 21
+ 1 2 5
? 3 1 5 5 5 1 5 1 3 5
?...

output:

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
-1
0
0
2
0
0
0
0
0
0
0
0
0
-1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
-1
0
0
0
1
0
0
0
0
0
0
0
0
0
-1
-1
0
-1
0
0
-3
0
0
0
0
0
0
0
0
0
0
0
2
1
0
-2
0
0
0
0
0
-1
4
0
0
0
0
7
0
0
0
0
0
2
0
0
1
0
-1
0
0
-2
0
0
0
0
0
0
0
-1
0
0
0
0
0
1
3
-1
0
1
0
0
-1
1
0
0
0
...

result:

wrong answer 10th lines differ - expected: '1', found: '0'