zoukankan      html  css  js  c++  java
  • bzoj2342 [Shoi2011]双倍回文 (manacher)

    2342: [Shoi2011]双倍回文

    Time Limit: 10 Sec Memory Limit: 128 MB
    Submit: 3787 Solved: 1472
    [Submit][Status][Discuss]
    ## Description ![](https://images2018.cnblogs.com/blog/1187622/201803/1187622-20180328101819404-1750679581.jpg) ## Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容。 ## Output 输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出0。

    看了好长时间,太差了;
    (R[k])为以(k)为中心的最长回文串,(x)(ww^Rww^R)对称轴,(y)为右半部分(ww^R)对称轴;
    (ch[x])(ch[y])一定为特殊字符,所以一定满足(R[x]>=2(y-x))(R[y]>=y-x)
    (x+R[x]/2>=y)(x>=y-R[y])
    所以把(y)(y-R[y])排序,枚举(x),把符合条件的(y)扔到(set)(upper)_(bound)一下就行了;
    AC GET☆DAZE

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define N 1000039
    #define mod 20070831
    #define inf 0x3f3f3f3f
    #define ll long long
    using namespace std;
    int n,m,R[N],stp[N],ans;
    char ch[N],rea[N];
    set<int> pos;
    set<int>::iterator th;
    int force(int &id,int &mx,int r)
    {
    	while(r<m)
    	{
    		if(rea[(id<<1)-r]!=rea[r]) break;
    		R[id]++,mx=r++;
    	}
    }
    void manacher()
    {
    	int id=1,mx=1;
    	for(int a=1,b;mx<m && a<m;a++)
    	{
    		if(a>=mx) force(id=a,mx,a+1);
    		else
    		{
    			b=(id<<1)-a;
    			if(R[b]<mx-a) R[a]=R[b];
    			else
    			{
    				R[a]=mx-a;
    				force(id=a,mx,mx+1);
    			}
    		}
    	}
    }
    bool cmp(int i,int j)
    {
    	return i-R[i]<j-R[j];
    }
    int main()
    {
    	scanf("%d",&n);
    	scanf(" %s",&ch);
    	rea[0]='3',rea[m=2*n+2]='9';
    	for(int a=1;a<m;a++)
    	{
    		if(a&1) rea[a]='#';
    		else rea[a]=ch[(a>>1)-1];
    		stp[a]=a;
    	}
    	manacher();
    	sort(stp+1,stp+m,cmp);
    	for(int a=1,b=1;a<m;a+=2)
    	{
    		while(b<m && stp[b]-R[stp[b]]<=a)
    		{
    			if(stp[b]&1) pos.insert(stp[b]);
    			b++;
    		}
    		th=pos.upper_bound(a+R[a]/2);
    		if(th!=pos.begin())
    		{
    			th--;
    			ans=max(ans,2*(*th-a));
    		}
    	}
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    __all__
    python内置函数
    qZnF新存马王至许观制两利各
    PHP中获取当前页面的完整URL
    DedeCms用tag调用全站相关文章
    dedecms如何利用tag来调取相关文章
    SQL Server TempDB
    SQL Server Pivot 隐藏group
    Rebind and Rewind in Execution Plans
    batch 数字进制的问题
  • 原文地址:https://www.cnblogs.com/Sinogi/p/8662255.html
Copyright © 2011-2022 走看看