zoukankan      html  css  js  c++  java
  • 【洛谷5446】[THUPC2018] 绿绿和串串(Manacher)

    点此看题面

    • 定义将一个串(R)翻转,是指将前(|R|-1)个字符复制一遍,倒序排列后插入到(R)的最后。
    • 现给定(R)若干次翻转后的串的一个前缀(|S|),求所有不超过(|S|)的可能的初始的(|R|)
    • (sum |S|le5 imes10^6)

    (Manacher)算法+倒序枚举

    考虑一个位置(i),如果(2i-1ge n)(即前缀(i)执行翻转操作会溢出),只需检验(i)的回文半径能否达到最右侧即可。

    而若(2i-1<n),首先(i)的回文半径能够达到最左侧,其次(2i-1)必须是一个可能的前缀。

    要求回文半径直接(Manacher),然后从大到小枚举位置(i)扫一遍即可。

    代码:(O(sum|S|))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 1000000
    using namespace std;
    int l;char s[N+5];
    namespace FastIO
    {
    	#define FS 100000
    	#define tc() (FA==FB&&(FB=(FA=FI)+fread(FI,1,FS,stdin),FA==FB)?EOF:*FA++)
    	#define pc(c) (FC==FE&&(clear(),0),*FC++=c)
    	int OT;char oc,FI[FS],FO[FS],OS[FS],*FA=FI,*FB=FI,*FC=FO,*FE=FO+FS;
    	I void clear() {fwrite(FO,1,FC-FO,stdout),FC=FO;}
    	Tp I void read(Ty& x) {x=0;W(!isdigit(oc=tc()));W(x=(x<<3)+(x<<1)+(oc&15),isdigit(oc=tc()));}
    	Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
    	I void reads(int& l,char* s) {l=0;W(isspace(oc=tc()));W(s[++l]=oc,!isspace(oc=tc())&&~oc);}
    	Tp I void write(Ty x) {W(OS[++OT]=x%10+48,x/=10);W(OT) pc(OS[OT--]);pc(' ');}
    	I void writeln() {pc('
    ');}
    }using namespace FastIO;
    namespace M
    {
    	int n,p[2*N+5];char g[2*N+5];I void Init()//对串预处理
    	{
    		RI i;for(g[0]='!',g[n=1]='%',i=1;i<=l;++i) g[++n]=s[i],g[++n]='%';g[++n]='?';//串头串间串尾加上奇怪字符
    	}
    	int f[N+5];I void Solve()
    	{
    		RI i,id,Mx=0;for(i=1;i<=n;i+p[i]>Mx&&(Mx=i+p[id=i]),++i)//Manacher
    			{p[i]=i<=Mx?min(p[id]+id-i,p[2*id-i]):1;W(g[i-p[i]]==g[i+p[i]]) ++p[i];}
    		RI x;for(i=n-2;i;i-=2) x=i>>1,f[x]=2*x-1>=l?i+p[i]==n:i-p[i]==0&&f[2*x-1];//倒序枚举,根据翻转后是否溢出讨论
    		for(i=1;i<=l;++i) f[i]&&(write(i),f[i]=0);writeln();//输出可能的前缀长度
    	}
    }
    int main()
    {
    	RI Tt;read(Tt);W(Tt--) reads(l,s),M::Init(),M::Solve();return clear(),0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    mybatis-cache model
    多线程开发(1)
    正则表达式(3) — 正则表达式库
    正则表达式(2) — 表达式规则
    我在迈瑞工作的两年总结
    正则表达式(1) — 常用的表达式
    C++系列(2) — 智能指针
    C++系列(1) — string
    路径去除前缀
    SIMD性能优化
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu5446.html
Copyright © 2011-2022 走看看