傳送門
這題……我覺得像我這樣的菜雞選手難以想出來……
題目要求求出一些子串行,使得其關於某個位置是對稱的,而且不能是連續一段,求這樣的子串行的個數。這個直接求很困難,但是我們可以先求出所有關於某個位置對稱的子串行,最後減去子串的個數。
子串個數可以用\(manacher\)求,至於子串行的話,我們假設以第\(i\)位為中心,那麼如果兩邊有\(x\)對相同的字元,那麼這個位置對答案的貢獻就是\(2^x-1\)或者\(2^(x+1)-1\)。(因為有可能回文串的長度是偶數,也就是不存在中間點)
考慮怎麼求\(x_i\)。\(x_i\)的形式可以寫成如下的形式:
\[\sum_^ic[i-j] == c[i+j]
\]發現這個式子非常像卷積的形式。那麼我們先初始化兩個序列,第乙個序列是原字串為『a』,對應位置為1,第二個是原字串為'b',對應位置是1,剩下都是0。這樣結果就轉化為如下形式:
\[\sum_^i a(i-j) * a(i+j) + b(i-j) * b(i+j)
\]然後讓他們自己和自己乘起來,結果相加一下,然後因為卷積會重複把元素計算兩遍,所以要+1再/2.
這樣得到的各項係數就是各項\(x_i\),我們就可以用快速冪計算。算完之後減去\(manacher\)求出的子串個數即可。
看一下**。
#include#include#include#include#include#include#include#include#include#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')
#define fr friend inline
#define y1 poj
#define mp make_pair
#define pr pair#define fi first
#define sc second
#define pb push_back
#define i puts("bug")
using namespace std;
typedef long long ll;
const int m = 200005;
const int inf = 1000000009;
const double eps = 1e-7;
const double pi = acos(-1);
const ll mod = 1e9+7;
int read()
while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
return ans * op;
}struct comp
comp(double kx,double ky)
fr comp operator + (const comp &a,const comp &b) ;}
fr comp operator - (const comp &a,const comp &b) ;}
fr comp operator * (const comp &a,const comp &b) ;}
}a[m<<1],b[m<<1],kx,ky;
int n,len = 1,l,p[m<<1],rev[m<<1];
char s[m<<1],c[m];
ll tot,d[m<<1],ans;
int change()
void manacher()
}void fft(comp *a,int f)}}
}ll qpow(ll a,ll b)
return p;
}int main()
while(len <= n << 1) len <<= 1,l++;
//i;
rep(i,0,len-1) rev[i] = (rev[i>>1] >> 1) | ((i&1) << (l-1));
fft(a,1),fft(b,1);
rep(i,0,len-1) a[i] = a[i] * a[i] + b[i] * b[i];
fft(a,-1);
rep(i,0,len-1) d[i] = ((ll)floor(a[i].x / len + 0.5) + 1) >> 1;
rep(i,0,len-1) ans += (qpow(2,d[i]) - 1),ans %= mod;
manacher(),ans -= tot,ans %= mod;
while(ans < 0) ans += mod;
printf("%lld\n",ans);
return 0;
}
BZOJ3160 萬徑人蹤滅
對於每個可以作為對稱軸的位置,我們算出以其為對稱軸有多少對位置和字元是對稱的,設為t i 若不考慮不能連續,則我們可以從這t i 對里任選出來任意對,都是可行的答案,且不重不漏,所以不考慮不能連續的情況的答案為sigma 2 t i 1,考慮不能是連續子串,再減去回文子串的數量即可 回文子串數量ma...
20178 27 萬徑人蹤滅 思考記錄
字串的題也可以fft 只要能化成卷積的形式就都可以fft 比如這裡的回文 對乙個位置 1 1 2 2 他們和相等,所以對a跑一邊,對b跑一遍,就相當於建出n次多項式然後求係數 注意manacher不要寫錯,漏寫最後一句 注意fft最後一句要寫在外面 碼 include include include...
BZOJ 3160 萬徑人蹤滅
給定乙個由 a 和 b 構成的字串,求不連續回文子串行的個數。正難則反我們考慮容斥。對於連續的回文字串顯然是一次馬拉車就可以很好的求出來的,那我們設f i 表示以i為中心的對稱字元對數量,顯然答案就是 2 n 1 12f i 1 那麼我們的問題就轉變成了怎麼求出f i 我們考慮當這個字元為a的時候做...