[SNOI2019] String explanations

Topic Link

Luo Gu P5329

sol

Title meaning is clear, but it seems not very good demand. Or take a look at part of the points.

10% Data

\ (\ Theta (n-2 ^ \ n-log) \) , violence, served 10 minutes.

Another 20% of the data

One thing I found, in comparison \ (S_I \) and \ (S_j \) , it is assumed \ (I <J \) , from 1 to i-1 is the same as this period, from j + 1 to n are the same , so long as we compare the original string and the i + 1 ~ j i ~ j-1 this is line two. Since any adjacent two are not the same, it is possible to \ (\ Theta (1) \ ) comparison.

Another 30% of the data

Think hash, hash although only sentence such as, but about half as long as we find the longest common prefix of two strings, and then comparing the position of the next longest common prefix on the line. Time complexity: \ (\ Theta (n-\ log ^ 2N) \)

Finally, 40% of the data

It should be very clear to the longest common prefix of two suffixes, immediately thought suffix array. By (n \ log n \) \ pretreatment can \ (\ Theta (1) \ ) compared reuse \ (\ Theta (n \ log n) \) of the quick drain it.

Found: TLE 60 minutes

Suffix array group seems constant is too large to pass. But think about what we need, the longest common prefix of two adjacent suffixes, you can set \ (h_i \) is the length of the longest common prefix to the suffix i and i + 1 at the beginning, it was obvious \ (h_i> H_-I. 1 {=} -1 \) , is the equivalent beginning with the removal of two characters, \ (H_i \) beginning assigned \ (I-H_ {-1}. 1 \) , can be \ ( \ Theta (n) \) pretreated array h, and finally sorted directly. Although the run, but many heavyweights \ (\ Theta (n) \ ) algorithm, but also through the.

code:

#include<bits/stdc++.h>
using namespace std;
#define cmp(a,b,c) (a+c<=n&&b+c<=n&&y[a]==y[b]&&y[a+c]==y[b+c])
#define min(a,b) (a<b?a:b)//卡常
const int maxn=1e6+10;
char s[maxn];
int ans[maxn],h[maxn],n;
inline void write(int x) {//卡常
    if(x>=10)write(x/10);
    putchar(x%10^48);
}
void Swap(int &a,int &b) {//还是卡常
    a^=b,b^=a,a^=b;
}
int cmp1(int a,int b) {//自定义比较方法
    int f=0;
    if(a>b)Swap(a,b),f=1;
    if(h[a]>=b-a)return f^1;
    return (s[a+h[a]+1]<s[a+h[a]])^f;
}
int t[maxn];
void Qsort(int l,int r) {//手写归并排序,也是写后缀数组卡常留下的
    if(l==r)return;
    int mid=(l+r)>>1;
    Qsort(l,mid),Qsort(mid+1,r);
    int i=l,j=mid+1,cnt=0;
    while(i<=mid||j<=r) {
        if((j>r)||(i<=mid&&cmp1(ans[i],ans[j])))t[cnt++]=ans[i++];
        else t[cnt++]=ans[j++];
    }
    for(int i=0; i<cnt; i++)ans[i+l]=t[i];
}
int main() {
    scanf("%d\n",&n);
    fread(s+1,1,n,stdin);//优读,写后缀数组卡常留下的
    for(int i=1; i<n; i++) {//求h数组
        h[i]=max(h[i-1]-1,0);
        for(int j=i+1; s[i+h[i]]==s[j+h[i]]; h[i]++);
    }
    for(int i=1; i<=n; i++)ans[i]=i;//初始化
    Qsort(1,n);
    for(int i=1; i<n; i++)write(ans[i]),putchar(' ');
    write(ans[n]),putchar('\n');
    return 0;
}

Guess you like

Origin www.cnblogs.com/hht2005/p/11462809.html