QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#410343#7506. StrCartesiangrass8cowRE 0ms26304kbC++174.5kb2024-05-13 21:51:572024-05-13 21:51:57

Judging History

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

  • [2024-05-13 21:51:57]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:26304kb
  • [2024-05-13 21:51:57]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#define pi pair<int,int>
#define fi first
#define se second
#define pb push_back
const int M=5e4+10,N=2e6+10;
int al[M],ar[M],bl[M],br[M];
char c[N];
int lg[N];
namespace Sa{
    int sa[N<<2],t[N<<2],rk[N<<2],tr[N<<2];
    int f[N][22],m;
    void build(int n){
        m=128;
        for(int i=1;i<=n;i++)t[rk[i]=c[i]]++;
        for(int i=1;i<=m;i++)t[i]+=t[i-1];
        for(int i=n;i;i--)sa[t[rk[i]]--]=i;
        for(int k=1;;k<<=1){
            int p=0;
            for(int i=n-k+1;i<=n;i++)tr[++p]=i;
            for(int i=1;i<=n;i++)if(sa[i]>k)tr[++p]=sa[i];
            for(int i=1;i<=m;i++)t[i]=0;
            for(int i=1;i<=n;i++)t[rk[i]]++;
            for(int i=1;i<=m;i++)t[i]+=t[i-1];
            for(int i=n;i;i--)sa[t[rk[tr[i]]]--]=tr[i];
            for(int i=1;i<=n;i++)tr[i]=rk[i];
            rk[sa[1]]=p=1;
            for(int i=2;i<=n;i++)
                rk[sa[i]]=(tr[sa[i-1]]==tr[sa[i]]&&tr[sa[i-1]+k]==tr[sa[i]+k])?p:(++p);
            if(p==n)break;m=p;
        }
        for(int i=1,k=0;i<=n;i++){
            int j=sa[rk[i]-1];
            while(i+k<=n&&j+k<=n&&c[i+k]==c[j+k])k++;
            f[rk[i]][0]=k;
        }
        for(int j=1;j<=20;j++)for(int i=1;i+(1<<j)-1<=n;i++)f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    }
    int lcp(int x,int y){
        x=rk[x],y=rk[y];if(x>y)swap(x,y);
        if(x==y)return N;
        x++;int k=lg[y-x+1];
        return min(f[x][k],f[y-(1<<k)+1][k]);
    }
    int cts(int ax,int bx,int ay,int by){
        vector<pi>x,y;
        x.pb({bl[bx],br[bx]});
        x.pb({al[ax],ar[ax]});
        y.pb({bl[by],br[by]});
        y.pb({al[ay],ar[ay]});
        while(!x.empty()&&!y.empty()){
            pi A=x.back(),B=y.back();x.pop_back(),y.pop_back();
            int lc=lcp(A.fi,B.fi),mo=min(A.se-A.fi+1,B.se-B.fi+1);
            if(lc<mo)return (c[A.fi+lc]<c[B.fi+lc])?1:-1;
            A.fi+=mo,B.fi+=mo;
            if(A.fi<=A.se)x.pb(A);
            if(B.fi<=B.se)y.pb(B);
        }
        if(!y.empty())return 1;
        if(!x.empty())return -1;
        return 0;
    }
}
int m;
namespace Trie{
    int ch[N][26],cn,sa[M],e,wh[N],bl_[M],br_[M];
    void dfs(int x){
        if(wh[x])sa[++e]=wh[x];
        for(int i=0;i<26;i++)if(ch[x][i])dfs(ch[x][i]);
    }
    void get(){
        cn=1;
        for(int i=1;i<=m;i++){
            int u=1;
            for(int j=bl[i];j<=br[i];j++){
                int z=c[j]-'a';
                if(!ch[u][z])ch[u][z]=++cn;
                u=ch[u][z];
            }
            wh[u]=i;
        }
        dfs(1);
        for(int i=1;i<=m;i++)bl_[i]=bl[sa[i]],br_[i]=br[sa[i]];
        for(int i=1;i<=m;i++)bl[i]=bl_[i],br[i]=br_[i];
    }
}
#define ll long long
mt19937 rnd(time(0));
int n,pl[50100],pr[50100],fi[50100],fi2[50100];
void Sol(ll k){
    for(int i=1;i<=n;i++)pl[i]=1,pr[i]=m;
    while(1){
        ll ns=0;
        for(int i=1;i<=n;i++)if(pl[i]<=pr[i])ns+=pr[i]-pl[i]+1;
        assert(ns);
        ll wh=(rnd()*rnd()%ns+ns)%ns;
        int X=-1,Y=-1;
        for(int i=1;i<=n;i++)if(pl[i]<=pr[i]){
            if(wh<pr[i]-pl[i]+1){X=i,Y=pl[i]+wh;break;}
            else wh-=pr[i]-pl[i]+1;
        }
        ll s1=0,s2=0;
        for(int i=1;i<=n;i++)if(pl[i]<=pr[i]){
            int l=pl[i],r=pr[i];
            fi[i]=fi2[i]=l-1;
            while(l<=r){
                int mi=(l+r)>>1;
                if(Sa::cts(i,mi,X,Y)==1)fi[i]=mi,l=mi+1;
                else r=mi-1;
            }
            s1+=fi[i]-pl[i]+1;
            l=pl[i],r=pr[i];
            while(l<=r){
                int mi=(l+r)>>1;
                if(Sa::cts(i,mi,X,Y)>=0)fi2[i]=mi,l=mi+1;
                else r=mi-1;
            }
            s2+=fi2[i]-pl[i]+1;
        }
        if(s1<k&&k<=s2){printf("%d %d\n",X,Y);return;}
        assert(s2);
        if(k<=s1){for(int i=1;i<=n;i++)if(pl[i]<=pr[i])pr[i]=fi[i];}
        else{k-=s2;for(int i=1;i<=n;i++)if(pl[i]<=pr[i])pl[i]=fi2[i]+1;}
    }
}
int ns;
int main(){
    lg[0]=-1;
    for(int i=1;i<=2000000;i++)lg[i]=lg[i>>1]+1;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s",c+ns+1);int L=strlen(c+ns+1);
        al[i]=ns+1,ar[i]=ns+L,ns+=L;
        pl[i]=1,pr[i]=m;
    }
    for(int i=1;i<=m;i++){
        scanf("%s",c+ns+1);int L=strlen(c+ns+1);
        bl[i]=ns+1,br[i]=ns+L,ns+=L;
    }
    Trie::get();Sa::build(ns);
    int q;scanf("%d",&q);
    ll K;
    while(q--)scanf("%lld",&K),Sol(K);
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 26304kb

input:

2 3
a
ab
a
aa
ba
2
3
4

output:

1 3
1 3

result:

ok Correct Answer

Test #2:

score: -100
Runtime Error

input:

27 28
ptdtljwzjbyctrjetnossaiogcfce
kmuwnsxjenpjybcwrecoqddbltzvnkzzrxvne
lsbqkpbgihqahpotzrnggqrompohf
ixonxrpixmurqgdtedhavpawmddfw
ruhqnxhvucv
fvarlrf
uyxxjzjf
tlzrxaykw
kldatopsv
fywmszxti
yraazxvbfebdhekphdrqhvpmferaghezebm
dovtqdvdd
waohxsasgl
biakvxhqx
aeyzaqum
repmbqtrvwd
dvqojkduc
sjxapwnyz...

output:


result: