博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3160:万径人踪灭
阅读量:5278 次
发布时间:2019-06-14

本文共 3082 字,大约阅读时间需要 10 分钟。

Description

Input & Output & Sample Input & Sample Output

HINT

 

题解:

题意即求不连续但间隔长度对称的回文串个数。

若si=sj,则这对字符可以作为以(i+j)/2为中心的回文串的一部分

用F[i]来表示可以做为以i/2为中心的回文串的一部分的字符对数,则以i/2为中心的回文串数为2^F[i]

则这就成了多项式乘法:先做一次a的,把字符为a的位置值赋为1,其余为0,进行一次FFT;同理做一次b的。

因为完全连续是不可以的,所以用Manacher求出这样的回文串的个数并减去。

 

代码:

(BZOJ上PASCAL跑得不够快,再加上这题时限只有10s,并没有AC,不知道那些用PASCAL通过的人是怎么卡常数的)

1 uses math; 2 const 3   mo=1000000007; 4 type 5   xs=record 6     x,y:double; 7   end; 8   arr=array[0..270001]of xs; 9 var10   e,t:arr;11   a:array[1..5]of arr;12   n,m,i,ll,ans:longint;13   ch:array[-2..270001]of char;14   b:array[-2..270001]of longint;15   z,ksm:array[0..270001]of longint;16   s:ansistring;17 operator -(a,b:xs)c:xs;18 begin c.x:=a.x-b.x; c.y:=a.y-b.y; end;19 operator +(a,b:xs)c:xs;20 begin c.x:=a.x+b.x; c.y:=a.y+b.y; end;21 operator *(a,b:xs)c:xs;22 begin c.x:=a.x*b.x-a.y*b.y; c.y:=a.x*b.y+a.y*b.x; end;23 procedure manacher;24 var k,l,i:longint;25 begin26   k:=-1; l:=-1; b[-1]:=1;27   for i:=0 to m*2-1 do28   begin29     if l>=i then30     b[i]:=min(b[2*k-i],l-i+1)else b[i]:=1;31     while true do32     begin33       if ch[i+b[i]]=ch[i-b[i]] then inc(b[i])34       else break;35     end;36     ans:=(ans+mo-(b[i]shr 1))mod mo;37     if i+b[i]-1>l then begin l:=i+b[i]-1; k:=i; end;38   end;39 end;40 procedure fft(xx:longint);41 var i,j,q,k,l,c:longint;42   t:xs;43 begin44   for i:=0 to n-1 do a[xx+2,z[i]]:=a[xx,i];45   xx:=xx+2;46   k:=n; l:=1;47   for i:=ll downto 1 do48   begin49     k:=k shr 1;50     for j:=0 to k-1 do51     begin52       c:=j*2*l;53       for q:=0 to l-1 do54       begin55         t:=e[q*k]*a[xx,c+l];56         a[xx,c+l]:=a[xx,c]-t;57         a[xx,c]:=a[xx,c]+t;58         inc(c);59       end;60     end;61     l:=l*2;62   end;63 end;64 begin65   readln(s); m:=length(s);66   ch[-2]:='+';67   for i:=0 to m-1 do ch[i*2]:=s[i+1];68   ch[m*2+1]:='-';69   manacher;70   for i:=0 to m-1 do if ch[i*2]='a' then a[1,i].x:=1;71   for i:=0 to m-1 do if ch[i*2]='b' then a[2,i].x:=1;72   n:=1;73   while n
PASCAL
1 #include
2 using namespace std; 3 int mo=1000000007; 4 typedef pair
pa; 5 pa operator + (pa a,pa b) 6 { pa c; c.first=a.first+b.first; c.second=a.second+b.second; return c; } 7 pa operator - (pa a,pa b) 8 { pa c; c.first=a.first-b.first; c.second=a.second-b.second; return c; } 9 pa operator * (pa a,pa b)10 { pa c; c.first=a.first*b.first-a.second*b.second; c.second=a.first*b.second+a.second*b.first; return c; }11 pa a[5][270005],e[270005];12 char s[270005],s2[270005];13 int n,ans,nn,m,ksm[270005],z[270005];14 void manacher()15 {16 int l=1,k=1; z[1]=0;17 for(int i=2;i<=nn;i++)18 {19 if(l>=i)z[i]=min(z[2*k-i],l-i);else z[i]=0;20 while(s2[i+z[i]+1]==s2[i-z[i]-1])z[i]++;21 ans=(ans-(z[i]+1)/2)%mo; if(i+z[i]>l){ k=i; l=i+z[i]; }22 }23 }24 void fft(int x)25 {26 for(int i=0;i
>1]>>1)+(i&1)*m/2;38 e[0].first=1; e[1].first=cos(2*acos(-1)/m); e[1].second=sin(2*acos(-1)/m);39 for(int i=2;i
C++

转载于:https://www.cnblogs.com/GhostReach/p/6257568.html

你可能感兴趣的文章
git - 搭建最简单的git server
查看>>
会话控制
查看>>
推荐一款UI设计软件Balsamiq Mockups
查看>>
Linux crontab 命令格式与详细例子
查看>>
百度地图Api进阶教程-地图鼠标左右键操作实例和鼠标样式6.html
查看>>
游标使用
查看>>
LLBL Gen Pro 设计器使用指南
查看>>
SetCapture() & ReleaseCapture() 捕获窗口外的【松开左键事件】: WM_LBUTTONUP
查看>>
Android 设置界面的圆角选项
查看>>
百度地图api服务端根据经纬度得到地址
查看>>
CSS中隐藏内容的3种方法及属性值
查看>>
每天一个linux命令(1):ls命令
查看>>
根据xml生成相应的对象类
查看>>
查看ASP.NET : ViewState
查看>>
Android StageFrightMediaScanner源码解析
查看>>
vue项目中开启Eslint碰到的一些问题及其规范
查看>>
循环队列实现
查看>>
获取表单提交的数据getParameter()方法
查看>>
CSS层模型
查看>>
springBoot 项目 jar/war打包 并运行
查看>>