zoukankan      html  css  js  c++  java
  • 撸串

     

     

     直接考虑有几种情况

    发现只能容错一次
    那就好搞了

    枚举循环节长度L


    case 1:错误不在区间[1,L]中
    那么循环节就是[1,L],直接hash判断是否后面是否相同,当遇到第一个不同时,就直接找出不同的删掉

    case 2:错误在区间[1,L]中
    那么循环节就一定是[L+1,L*2+1],和上面的一样判断
    然后就没了。

    主要就是枚举循环节长度L这个有点难想,一旦想到了那就简单了

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=200005;const int mod=1000000007;
    int T,n;char s[N];ll hash[N],H[N];
    inline ll read()
    {
        char c=getchar();ll a=0,b=1;
        for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
        for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;
        return a*b;
    }
    inline void hash_pre()
    {
        hash[0]=1;
        for(int i=1;i<=N-4;i++)
        {
            hash[i]=233*hash[i-1]%mod;
        }
    }
    inline int equal(int l,int r,int a,int b)
    {
        return (((H[r]-H[l-1]*hash[r-l+1]%mod+mod)%mod)-(H[b]-H[a-1]*hash[b-a+1]%mod+mod)%mod)==0;
    }
    inline int miss(int l,int r,int a,int b)
    {
        int L=0,R=b-a+1,ans;
        while(L<=R)
        {
            if(equal(l,l+((L+R)>>1)-1,a,a+((L+R)>>1)-1))
            {
                ans=((L+R)>>1);
                L=((L+R)>>1)+1;
            }
            else R=((L+R)>>1)-1;
        }
        return ans+1; 
    }
    int main()
    {
        freopen("string.in","r",stdin);
        freopen("string.out","w",stdout);
        T=read();
        hash_pre();
        int i,j;
        while(T--)
        {
            n=read();
            scanf("%s",s+1);
            H[0]=0;
            if(n<2)
            {
                puts("0");
                break;
            }
            for(i=1;i<=n;i++)
            {
                H[i]=((H[i-1]*233)%mod+s[i])%mod;
            }
            for(i=1;i<n;i++)
            {
                if(i*2+1<=n)
                {
                    int az=miss(1,i,i+2,i*2+1);
                    if(az==n+1||(az<=n&&equal(az+1,i+1,i+1+az,i+i+1)))
                    {
                        for(j=i*2+2;j<=n-i+1;j+=i)
                        {
                            if(equal(2+i,i+i+1,j,j+i-1)==false)break;
                        }
                        if(j+i-1>n&&equal(i+2,i+2+n-j,j,n))break;
                    }
                }
                else
                {
                    int az=miss(1,n-i-1,i+2,n);
                    if(az==n-i)break;
                    else 
                    {
                        if(equal(az+1,n-i,i+az+1,n))break;
                    }
                }
                for(j=i+1;j+i-1<=n;j+=i)
                {
                    if(!equal(1,i,j,i+j-1))break;
                }
                if(j+i-1<=n)
                {
                    int az=miss(1,i,j,i+j-1);
                    if(j+i-1==n&&equal(az,i-1,j+az,n))break;
                    else if(equal(az,i,j+az,j+i))
                    {
                        for(j+=i+1;j+i-1<=n;j+=i)
                        {
                            if(!equal(1,i,j,i+j-1))break;
                        }
                        if(j>n||(j+i-1>n&&equal(1,n-j+1,j,n)))break;
                    }
                }
                else
                {
                    if(equal(1,n-j+1,j,n))break;
                    else
                    {
                        int az=miss(1,n-j+1,j,n);
                        if(equal(az,n-j,az+j,n))break;
                    }
                }
            }
            cout<<i<<endl;
        }
        return 0;
    }
  • 相关阅读:
    windows server 2008 r2 切换windows 7主题方法
    JAVA环境安装
    Oracle 11gR2 安装教学
    webmin-1.810 安装
    Windows Squid 安装配置
    Zyxel Switch-How to block a fake DHCP server without enabling DHCP snooping?
    Java介绍
    cookies和session区别
    牛刀小试之Django二
    小试牛刀之Django
  • 原文地址:https://www.cnblogs.com/HLZZPawa/p/13537616.html
Copyright © 2011-2022 走看看