QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#188988 | #6844. Suffix Automaton | qzzyq | WA | 7ms | 38748kb | C++14 | 4.3kb | 2023-09-26 18:35:48 | 2023-09-26 18:35:48 |
Judging History
answer
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define maxn 1000005
#define put() putchar('\n')
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
using namespace std;
void read(int &x){
int f=1;x=0;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
x*=f;
}
namespace Debug{
Tp void _debug(char* f,Ty t){cerr<<f<<'='<<t<<endl;}
Ts void _debug(char* f,Ty x,Ar... y){while(*f!=',') cerr<<*f++;cerr<<'='<<x<<",";_debug(f+1,y...);}
Tp ostream& operator<<(ostream& os,vector<Ty>& V){os<<"[";for(auto& vv:V) os<<vv<<",";os<<"]";return os;}
#define gdb(...) _debug((char*)#__VA_ARGS__,__VA_ARGS__)
}using namespace Debug;
#define fi first
#define se second
#define mk make_pair
const int mod=1e9+7;
int power(int x,int y=mod-2) {
int sum=1;
while (y) {
if (y&1) sum=sum*x%mod;
x=x*x%mod;y>>=1;
}
return sum;
}
char s[maxn];
int rk[maxn],n,m,oldrk[maxn],sa[maxn],id[maxn],cnt[maxn],height[maxn];
int ls[maxn],rs[maxn],g[maxn],d[maxn];
pair<int,int>Ans[maxn];
struct yyy {
int id,l,x;
}q[maxn];
struct node{
int lazy,Min,id;
}f[maxn<<2];
void pushup(int rt) {
f[rt].Min=min(f[rt<<1].Min,f[rt<<1|1].Min);
if (f[rt].Min==f[rt<<1].Min) f[rt].id=f[rt<<1].id;
else f[rt].id=f[rt<<1|1].id;
}
void pushdown(int rt) {
if (f[rt].lazy) {
int k=f[rt].lazy;f[rt].lazy=0;
f[rt<<1].lazy+=k,f[rt<<1|1].lazy+=k;
f[rt<<1].Min+=k,f[rt<<1|1].Min+=k;
}
}
void Update(int l,int r,int rt,int head,int tail,int k) {
if (head<=l&&r<=tail) {
if (l==r) f[rt].id=l;
f[rt].Min+=k,f[rt].lazy+=k;
return ;
}
int mid=l+r>>1;pushdown(rt);
if (head<=mid) Update(l,mid,rt<<1,head,tail,k);
if (tail>mid) Update(mid+1,r,rt<<1|1,head,tail,k);
pushup(rt);
}
bool cmp(yyy x,yyy y) {return x.l<y.l;}
const int inf=1e9;
int fr[maxn][21],lg[maxn];
int query(int x,int y) {
if (y>x) return inf;
int z=lg[y-x+1];
return min(fr[x][z],fr[y-(1<<z)+1][z]);
}
signed main(void){
int i,j,p,w,k,T,l,r,mid;
scanf("%s",s+1);for (n=1;s[n];n++) ;n--;m=127;
for (i=1;i<=n;i++) cnt[rk[i]=s[i]]++;
for (i=1;i<=m;i++) cnt[i]+=cnt[i-1];
for (i=1;i<=n;i++) sa[cnt[rk[i]]--]=i;
memcpy(oldrk,rk,sizeof(oldrk));
for (p=0,i=1;i<=n;i++) if (oldrk[sa[i]]==oldrk[sa[i-1]]) rk[sa[i]]=p;else rk[sa[i]]=++p;
// for (i=1;i<=n;i++) gdb(i,rk[i],sa[i]);
for (w=1;w<n;w<<=1) {
for (p=0,i=n;i>n-w;i--) id[++p]=i;
for (i=1;i<=n;i++) if (sa[i]>w) id[++p]=sa[i]-w;
memcpy(oldrk,rk,sizeof(oldrk));
memset(cnt,0,sizeof(cnt));
for (i=1;i<=n;i++) cnt[rk[id[i]]]++;
for (i=1;i<=n;i++) cnt[i]+=cnt[i-1];
for (i=n;i>=1;i--) sa[cnt[rk[id[i]]]--]=id[i];
for (p=0,i=1;i<=n;i++) if (oldrk[sa[i]]==oldrk[sa[i-1]]&&oldrk[sa[i]+w]==oldrk[sa[i-1]+w]) rk[sa[i]]=p;else rk[sa[i]]=++p;
}
// for (i=1;i<=n;i++) printf("%d ",sa[i]);
// gdb(n);
for (k=0,i=1;i<=n;i++) {
if (rk[i]==0) continue;
if (k) k--;
while (s[i+k]==s[sa[rk[i]-1]+k]) ++k;
height[rk[i]]=k;
}
for (i=1;i<=n;i++) g[i]=g[i-1]+(n-sa[i]+1)-height[i],d[height[i]+1]++,d[n-sa[i]+2]--;//,gdb(i,height[i]+1,n-sa[i]+1);
for (i=1;i<=n;i++) d[i]+=d[i-1];
for (i=1;i<=n;i++) d[i]+=d[i-1];
read(T);
for (i=1;i<=T;i++) {
read(k);
if (k>d[n]) {q[i].id=i,q[i].l=n,q[i].x=inf;continue;}
int tot=lower_bound(d+1,d+1+n,k)-d;
q[i].id=i,q[i].l=tot,q[i].x=k-d[tot-1];
}
sort(q+1,q+1+T,cmp);
for (i=1;i<=T;i++) {
Update(1,T,1,i,i,q[i].x);
if (!ls[q[i].l]) ls[q[i].l]=i;
rs[q[i].l]=i;
}
for (i=1;i<=n;i++) if (!rs[i]) rs[i]=rs[i-1];
for (i=n;i>=1;i--) if (!ls[i]) ls[i]=ls[i+1];
for (i=1;i<=n;i++) {
if (ls[height[i]+1]<=rs[n-sa[i]+1]) Update(1,T,1,ls[height[i]+1],rs[n-sa[i]+1],-1);
while (f[1].Min==0) {
Ans[q[f[1].id].id]=mk(sa[i],q[f[1].id].l);
Update(1,T,1,f[1].id,f[1].id,inf);
}
}
// if (n>=96) putchar(s[96]);
for (i=1;i<=n;i++) fr[i][0]=height[i];
for (j=1;j<=20;j++) for (i=1;i+(1<<j)-1<=n;i++) fr[i][j]=min(fr[i][j-1],fr[i+(1<<j-1)][j-1]);
for (i=1;i<=T;i++) if (Ans[i].fi!=0) {
l=rk[Ans[i].fi],r=n+1;
while (l+1<r) {
mid=l+r>>1;
if (query(sa[Ans[i].fi]+1,mid)>=Ans[i].se) l=mid;
else r=mid;
}
printf("%d %d\n",sa[l],sa[l]+Ans[i].se-1);
// printf("%d %d\n",Ans[i].fi,Ans[i].se);
} else puts("-1 -1");
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 7ms
memory: 38748kb
input:
ccpcguilin 5 1 10 4 8 26
output:
6 6 6 7 8 8 6 7 4 7
result:
wrong answer 1st lines differ - expected: '1 1', found: '6 6'