A Horrible Poem

https://loj.ac/problem/10038

Title Description

  Given a string S, and q interrogation times, each interrogation cycle section shortest substring of string.

Thinking

  This question is cancer problem, it must be cancer problem, at least loj data Yes. I have two ideas, a 93 points, 97 points a read not accelerate, accelerate read out.

   First, it is clear that the minimum requirements for a string loop section, enumerated its prefix length factor. But this will obviously be T, we consider optimization.

   We can consider by preprocessing ①, the number of all the letters quickly determined within a sub-string, and the number of letters minimum cycle section must be a common factor of the number of all the letters, then the minimum number of cycles section must be the common factor of a factor is it possible to be circulating section. So we enumerate [1  ], to see whether the loop section, updated the answer. The last 93 minutes.

   ② reason the first practice run does not enumerate the past is useless when there are too many states, but it is difficult to continue to optimize, we start again from the original idea. We want the minimum cycle length section, it must also be a multiple loop section. We first remove the smallest prime factor of the number of all original string length linear sieve. After each substring query asking the prime factorization of length, each of which is determined quality factor, divided by the try each quality factor, shrinking len, the final answer is the smallest circular section.

Code (method a, 93 minutes)

#include <bits / stdc ++. h>
 using  namespace std; 
typedef unsigned long  long eye;
const eye p = 131 , MAXN 5e5 + = 10 ;
char s [MAXN]; 
Eye sum [MAXN] power [MAXN] years; 
look f [MAXN] [ 30 ]; 
f_hash eye (the eye, eye r) 
{ 
    return (eye) sum [r] -sum [L- 1 ] * Power [l + r- 1 ]; 
} 
Eye gcd (eye x, eye y) 
{ 
    return y == 0 ? X: GCD (y, x% y); 
} 
Void check (the eye, eye r eye len) 
{ 
    if(f_hash(l,r-len)==f_hash(l+len,r))
        ans=min(ans,len);
}
ull read()
{
    ull ret=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
    return ret*w;
}
int main() 
{
    ull n;
    n=read();
    gets(s+1);
    power[0]=1;
    for(ull i=1;i<=n;i++)
    {
        sum[i]=sum[i-1]*p+(s[i]-'a'+1);
        power[i]=power[i-1]*p;
    }
    for(ull i=1;i<=n;i++)
    {
        for(ull j=1;j<=26;j++)
            f[i][j]=f[i-1][j];
        f[i][s[i]-'a'+1]++;
    }
    ull q;
    q=read();
    while(q--)
    {
        ull l,r;
        l=read();r=read();
        ull len=r-l+1,vgcd=r-l+1;
        for(ull i=1;i<=26;i++)
            vgcd=gcd(vgcd,f[r][i]-f[l-1][i]);
        ans=1e9;
        for(ull i=1;i*i<=vgcd;i++)
            if(vgcd%i==0)
            {
                check(l,r,len/i);
                check(l,r,len/(vgcd/i));
            }
        printf("%llu\n",ans);
    }
    return 0;
}

Code (positive solution, out)

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const ull p=47,MAXN=5e5+10;
char s[MAXN];
ull sum[MAXN],power[MAXN],ans,ys[MAXN],prime[MAXN],nxt[MAXN];
bool used[MAXN];
ull f_hash(ull l,ull r)
{
    return (ull)sum[r]-sum[l-1]*power[r-l+1];
}
bool check(ull l,ull r,ull len)
{
    return f_hash(l,r-len)==f_hash(l+len,r);
}

ull read()
{
    ull res=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();}
    return res*w;
}
void write(ull x)
{
    if(x>9)write(x/10);
    putchar(x%10^48);
}
void writeln(ull x)
{
    write(x);
    putchar('\n');
}

void pri()
{
    ull k=0;
    for(ull i=2;i<=MAXN;i++)
    {
        if(!used[i])
        {
            prime[++k]=i;
            nxt[i]=i;
        }
        for(int j=1;j<=k&&i*prime[j]<=MAXN;j++)
        {
            ull m=i*prime[j];
            used[m]=1;
            nxt[m]=prime[j];
            if(i%prime[j]==0)break ;
        }
    }
}
int main() 
{
    ull n=read();
    scanf(" %s",s+1);
    power[0]=1;
    for(ull i=1;i<=n;i++)
    {
        sum[i]=sum[i-1]*p+(s[i]-'a'+1);
        power[i]=power[i-1]*p;
    }
    pri();
    ull q=read();
    while(q--)
    {
        ull l=read(),r=read();
        ull len=r-l+1,cnt=0;
        while(len!=1)
        {
            ys[++cnt]=nxt[len];
            len/=nxt[len];
        }
        len=r-l+1;
        for(int i=1;i<=cnt;i++)
        {
            int tmp=len/ys[i];
            if(check(l,r,tmp))
                len=tmp;
        }
        writeln(len);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/fangbozhen/p/11620725.html