O ( ∑ i = 1 Q ( r i − l i ) ) O(\sum_{i=1}^{Q}(r_i-l_i) ) O(i=1∑Q(ri−li))
a n s [ i ] [ j ] 为 [ l , r ] 的答案 ans[i][j] ~为[l , r]的答案 ans[i][j] 为[l,r]的答案
a n s [ l ] [ r ] = a n s [ l ] [ r − 1 ] + p r e [ l ] [ r ] ans[l][r]=ans[l][r-1]+pre[l][r] ans[l][r]=ans[l][r−1]+pre[l][r]
p r e [ l ] [ r ] = p r e [ l ] [ r − 1 ] + d p [ l ] [ r ] pre[l][r] = pre[l][r-1]+dp[l][r] pre[l][r]=pre[l][r−1]+dp[l][r]
转移方程: d p [ l ] [ r ] ∣ = ( d p [ l + 1 ] [ r − 1 ] & & ( s [ l ] = = s [ r ] ) ) 转移方程:dp[l][r] |= (dp[l + 1][r - 1] ~~\&\&~~ (s[l] == s[r])) 转移方程:dp[l][r]∣=(dp[l+1][r−1] && (s[l]==s[r]))
#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
//#define int long long
const int INF = 9e18;
const int N = 5e3 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;
int ans[N][N] , pre[N][N];
bool dp[N][N];
int n , q;
string s;
signed main(){
IOS
cin >> s;
n = s.size();
s = '?' + s;
for(int i = 1 ; i <= n ; i ++) dp[i][i] = 1;
for(int i = 1 ; i < n ; i ++) dp[i][i + 1] = (s[i] == s[i + 1]);
for(int len = 3 ; len <= n ; len ++) {
for(int l = 1 ; l <= n ; l ++) {
int r = l + len - 1;
dp[l][r] |= (dp[l + 1][r - 1] && (s[l] == s[r]));
}
}
for(int r = 1 ; r <= n ; r ++) {
for(int l = r ; l >= 1 ; l --){
pre[l][r] = pre[l + 1][r] + dp[l][r];
}
}
for(int l = 1 ; l <= n ; l ++) {
for(int r = l ; r <= n ; r ++) {
ans[l][r] = ans[l][r - 1] + pre[l][r];
}
}
cin >> q;
while(q --) {
int l , r;
cin >> l >> r;
cout << ans[l][r] << "\n";
}
return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);
#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
//#define int long long
//const int INF = 9e18;
const int N = 5e3 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;
int ans[N][N] , pre[N][N];
bool dp[N][N];
int n , q , m;
string s , t;
int d[N * 2 + 1];
//给出一个字符串求d[i]数组并返回马拉车串
string manacher(string s){
string now = "#$";
int n = s.size();
for(int i = 0 ; i < n ; i ++) now += s[i] , now += '$';
n = now.size();
d[1] = 1;
for(int i = 2 , l , r = 1; i < n ; i ++){
if(i <= r) d[i] = min(d[r - i + l] , r - i + 1);
else d[i] = 1;
while(now[i - d[i]] == now[i + d[i]]) d[i] += 1;
if(i + d[i] - 1 > r) l = i - d[i] + 1 , r = i + d[i] - 1;
}
return now;
}
void watch(string s){
int n = s.size();
for(int i = 0 ; i < n ; i ++) cout << s[i] << " ";
cout << "\n";
for(int i = 0 ; i < n ; i ++) cout << d[i] << " ";
cout << "\n";
}
signed main(){
IOS
cin >> s;
n = s.size();
t = manacher(s);
m = t.size();
// watch(s);
int len = 0 , l = 0 , r = 0;
for(int i = 1 ; i <= m ; i ++) {
if(i & 1) {//偶回文中心
len = (d[i] - 1) / 2;
l = (i - 1) / 2;
r = (i + 1) / 2;
} else {
len = d[i] / 2;
l = r = i / 2;
}
for(int i = 1 ; i <= len ; i ++ , l -= 1 , r += 1) {
dp[l][r] = 1;
}
}
for(int r = 1 ; r <= n ; r ++) {
for(int l = r ; l >= 1 ; l --){
pre[l][r] = pre[l + 1][r] + dp[l][r];
}
}
for(int l = 1 ; l <= n ; l ++) {
for(int r = l ; r <= n ; r ++) {
ans[l][r] = ans[l][r - 1] + pre[l][r];
}
}
cin >> q;
while(q --) {
int l , r;
cin >> l >> r;
cout << ans[l][r] << "\n";
}
return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);
#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int INF = 9e18;
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;
#define ull unsigned long long
const int Base = 131;
ull base[N] , hx[N] , hy[N];
string x , y;
int n;
int cntx[N][2] , cnty[N][2];
//-------------------------------------------------------------
//求[l , r) 的散列值 (从 0 开始)
inline ull get_x(int l,int r){
return hx[r] - hx[l] * base[r - l];
}
inline ull get_y(int l,int r){
return hy[r] - hy[l] * base[r - l];
}
bool ask(int lx , int rx , int ly , int ry) {
lx += 1;ly += 1;rx += 1;ry += 1;
return (cntx[rx][0] - cntx[lx - 1][0] != cnty[ry][0] - cnty[ly - 1][0]) || (cntx[rx][1] - cntx[lx - 1][1] != cnty[ry][1] - cnty[ly - 1][1]);
}
/*
哈希 + 递归搜索剪枝
两次剪枝
*/
bool judge(int lx , int rx , int ly , int ry) {
if(get_x(lx , rx + 1) == get_y(ly , ry + 1)) return 1;
else {
int len = rx - lx + 1;
if(len & 1) {
return 0;
} else {
int mid = len / 2;
bool tag1 = 0 , tag2 = 0;
if(ask(lx , lx + mid - 1 , ly , ly + mid - 1) || ask(lx + mid , rx , ly + mid , ry)) tag1 = 0;
else tag1 = (judge(lx , lx + mid - 1 , ly , ly + mid - 1) && judge(lx + mid , rx , ly + mid , ry));
if(tag1) return 1;
if(ask(lx , lx + mid - 1 , ly + mid , ry) || ask(lx + mid , rx , ly , ly + mid - 1)) tag2 = 0;
else tag2 = (judge(lx , lx + mid - 1 , ly + mid , ry) && judge(lx + mid , rx , ly , ly + mid - 1));
if(tag2) return 1;
return 0;
}
}
}
signed main(){
cin >> x >> y;
n = x.size();
base[0] = 1;
for(int i = 1 ; i <= n ; i ++) base[i] = base[i - 1] * Base;
hx[0] = 0;
for(int i = 1 ; i <= n ; i ++) {
hx[i] = hx[i - 1] * Base + x[i - 1];
cntx[i][0] = cntx[i - 1][0] + (x[i - 1] == 'a');
cntx[i][1] = cntx[i - 1][1] + (x[i - 1] == 'b');
}
hy[0] = 0;
for(int i = 1 ; i <= n ; i ++) {
hy[i] = hy[i - 1] * Base + y[i - 1];
cnty[i][0] = cnty[i - 1][0] + (y[i - 1] == 'a');
cnty[i][1] = cnty[i - 1][1] + (y[i - 1] == 'b');
}
if(judge(0 , n - 1 , 0 , n - 1)) {
cout << "YES\n";
} else {
cout << "NO\n";
}
return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);
复杂度 O ( n n ) 复杂度O(n\sqrt n) 复杂度O(nn)
#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int INF = 9e18;
const int N = 2e5 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;
/*
ans = all - 区间异或值为平方数的区间个数
*/
int n , t , a[N];
int v[N] , cnt;
signed main(){
IOS
cin >> t;
while(t --) {
cin >> n;
for(int i = 1 ; i <= n ; i ++) {
cin >> a[i];
}
cnt = 0;
v[++cnt] = 0;
for(int i = 1 ; i * i <= 2 * n ; i ++) v[++cnt] = i * i;
//注意思考这里的空间为什么开四倍
vector<int>pre(4 * n + 1);
int res = 0 , ans = (n + 1) * n / 2 , now = 0;
pre[0] = 1;
for(int i = 1 ; i <= n ; i ++) {
now ^= a[i];
for(int j = 1 ; j <= cnt ; j ++) {
res += pre[now ^ v[j]];
}
pre[now] += 1;
}
cout << ans - res << "\n";
}
return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);
#include
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int INF = 9e18;
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;
int nex[N];
void init(string s){
int len = s.size();
nex[1] = 0;
for(int i = 2 ; i <= len ; i ++){
nex[i] = nex[i-1];
while(nex[i] && s[nex[i]] != s[i-1]) nex[i] = nex[nex[i]];
nex[i] += (s[i-1] == s[nex[i]]);
}
}
string s;
int n;
signed main(){
cin >> s;
n = s.size();
init(s);
bool ok = 0;
int ans = -1;
vector<bool>tag(n + 1);
int now = nex[n];
while(now) {
tag[now] = 1;
now = nex[now];
}
string now_s , now_k;
for(int i = 1 ; i < n ; i ++) {
now_s = s.substr(i) + s.substr(0 , i);
if(now_s == s) continue;
now_k = now_s;
reverse(now_k.begin() , now_k.end());
if(now_s != now_k) continue;
ok = 1;
}
if(ok == 1) {
ans = 1;
} else {
for(int i = 1 ; i <= n / 2 ; i ++) if(!tag[i]) ans = 2;
}
if(ans == -1) {
cout << "Impossible\n";
} else {
cout << ans << "\n";
}
return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);