【[POI2010]ANT-Antisymmetry】
阿新 • • 發佈:2019-01-01
開始複習字串了
第一步肯定得是\(hash\)
首先理性分析一波不可能出現長度為奇數的反迴文串,對稱軸位置取反之後肯定和原來不相等了
我們可以列舉所有迴文串的對稱中心,之後我們發現這個樣子是具有單調性de
於是我們就利用\(hash\)來判斷
將原來的串取反之後在反轉,判斷在對稱中心左右兩邊二分的長度是否相等就可以啦
程式碼
#include<iostream> #include<cstdio> #include<cstring> #define re register #define ull unsigned long long #define maxn 500005 #define min(a,b) ((a)<(b)?(a):(b)) char S[maxn],T[maxn]; int a[maxn],b[maxn]; int n; ull ha[maxn],sh[maxn]; ull pow[maxn]; ull base=17; long long num; inline ull get_hash(int l,int r,int op) { if(!op) return ha[r]-ha[l-1]*pow[r-l+1]; return sh[n-l+1]-sh[n-r]*pow[r-l+1]; } int main() { scanf("%d",&n); scanf("%s",S+1); for(re int i=1;i<=n;i++) if(S[i]=='0') a[i]=0; else a[i]=1; pow[0]=1; for(re int i=1;i<=n;i++) pow[i]=pow[i-1]*base; for(re int i=1;i<=n;i++) ha[i]=ha[i-1]*base+(a[i]+1); for(re int i=1;i<=n;i++) b[i]=a[n-i+1]^1; for(re int i=1;i<=n;i++) sh[i]=sh[i-1]*base+(b[i]+1); for(re int i=1;i<n;i++) { int l=1,r=min(i,n-i); int ans=0; while(l<=r) { int mid=l+r>>1; if(get_hash(i-mid+1,i,1)==get_hash(i+1,i+mid,0)) l=mid+1,ans=mid; else r=mid-1; } num+=ans; } printf("%lld\n",num); return 0; } /* 8 11001011 */