• 马拉车(manacher)


    (注意:本博客只作为模板,不适合刚学manacher的人看)

    (几个关键点大概可以表示成这样)

    (ct-p[ct]----j---ct---i----ct+p[ct])

    (因为p[i]<=p[j],所以p[i]=min(p[2ct-i],ct+p[ct]-i))

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=51000100;
    int n,p[maxn],ans;
    char a[maxn],s[maxn<<1];
    void init()
    {
    	s[0]=s[1]='#';
    	for(int i=0;i<n;i++)
    	{
    		s[i*2+2]=a[i];
    		s[i*2+3]='#';
    	}
    	n=n*2+2;
    	s[n]=0;
    }
    int manacher()
    {
    	int maxright=0,ct,ans=0;
    	for(int i=1;i<n;i++)
    	{
    		if(i<maxright)	p[i]=min(p[ct*2-i],p[ct]+ct-i);
    		//----j----ct----i----ct+p[ct]
    		//可知j=ct*2-i,但是p[i]最大是(p[ct]+ct)-i 
    		else	p[i]=1;
    		for(;s[i+p[i]]==s[i-p[i]];++p[i]) 
    		if(p[i]+i>maxright)	maxright=p[i]+i,ct=i;
    		ans=max(ans,p[i]);
    	}
    	return ans-1;
    }
    int main()
    {
    	cin>>a;
    	n=strlen(a);
    	init();
    	cout<<manacher();
    }
    

    (color{Orange}{附上一道练手题,cf的})

    永久打开的传送门

    #include <bits/stdc++.h>
    using namespace std;
    string Manacher(const string &s){
        string t="#";
        for(char c:s) t+=c,t+="#";
        int RL[t.size()]={0};
        int MaxRight=0;
        int pos=0;
        for(int i=0;i<t.size();i++){
            if(i<MaxRight)
                RL[i]=min(RL[2*pos-i],MaxRight-i);
            else
                RL[i]=1;
            while(i-RL[i]>=0&&i+RL[i]<t.size()&&t[i-RL[i]]==t[i+RL[i]])
                RL[i]+=1;
            if(RL[i]+i-1>MaxRight)
                pos=i,MaxRight=RL[i]+i-1;
        }
        int MaxLen=0;
        for(int i=0;i<t.size();i++)
            if(RL[i]==i+1)
                MaxLen=i;
        return s.substr(0,MaxLen);
    }
    void solve(){
        string s;cin>>s;
        int l=0,r=s.size()-1;
        while(l<r&&s[l]==s[r]) ++l,--r;
        string s1=s.substr(l,r-l+1);
        string s2=s1;
        reverse(s2.begin(),s2.end());
        s1=Manacher(s1);
        s2=Manacher(s2);
        cout<<s.substr(0,l)<<(s1.size()>s2.size()?s1:s2)<<s.substr(r+1)<<"
    ";
    }
    int main()
    {
        int t;cin>>t;
        while(t--)
            solve();
        return 0;
    }
    
    
  • 相关阅读:
    点击子窗体给父窗体上的对象赋值
    框架使用及规范参考
    像Google日历一样的日程管理
    TreeView 和 Menu 的用法
    甘特图-svg版 支持客户端事件
    js获取DropDownList的选择项
    GridView,Repeater分页控件:WebPager(开源)
    TextBox 禁止客户端输入 前台通过JS赋值 并在后台获取
    对象实体 参考标准
    以编程方式控制ScriptManager
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12863392.html
Copyright © 2020-2023  润新知