[BZOJ2084] [Poi2010]Antisymmetry

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=2084

题目大意

给定一个长度为n的01串,问有多少个子串满足翻转并取反后和原来一样

题解

manacher裸题
但是我不会manacherQAQAQ
所以我就二分+HASH水过去了~~
还是要学manacher的~~

const
    maxn=500005;
    seed=131;
    mmod=1000173169;
var
    g,h,pow:array[0..maxn]of int64;
    x,y:array[0..maxn]of char;
    i,j,k:longint;
    n,tt:longint;
    ans:int64;
function min(a,b:longint):longint;
begin
    if a>b then exit(b) else exit(a);
end;

function hash1(l,r:longint):int64;
var a:longint;
begin
    a:=r;
    r:=n-l+1;
    l:=n-a+1;
    exit((h[r]-h[l-1]*pow[r-l+1] mod mmod+mmod)mod mmod);
end;

function hash2(l,r:longint):int64;
begin
    exit((g[r]-g[l-1]*pow[r-l+1] mod mmod+mmod)mod mmod);
end;

function query(a:longint):longint;
var l,r,mid,ans:longint;
begin
    ans:=0; l:=1; r:=min(a,n-a);
    while l<=r do
        begin
            mid:=(l+r)>>1;
            if hash1(a-mid+1,a)=hash2(a+1,a+mid)
            then begin ans:=mid; l:=mid+1; end
            else r:=mid-1;
        end;
    exit(ans);
end;

begin
    readln(n); pow[0]:=1;
    for i:=1 to n do
        pow[i]:=(pow[i-1]*seed)mod mmod;
    g[0]:=0;
    for i:=1 to n do
        begin
            read(x[i]);
            if x[i]='1'
            then y[n-i+1]:='0' else y[n-i+1]:='1';
            g[i]:=(g[i-1]*seed+ord(x[i]))mod mmod;
        end;
    readln;
    h[0]:=0;
    for i:=1 to n do
        h[i]:=(h[i-1]*seed+ord(y[i]))mod mmod;
    ans:=0;
    for i:=1 to n do
        begin
            tt:=query(i);
            inc(ans,tt);
        end;
    writeln(ans);
end.

你可能感兴趣的:([BZOJ2084] [Poi2010]Antisymmetry)