結果
| 問題 |
No.263 Common Palindromes Extra
|
| コンテスト | |
| ユーザー |
chocorusk
|
| 提出日時 | 2020-05-02 06:56:41 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,404 ms / 2,000 ms |
| コード長 | 2,660 bytes |
| コンパイル時間 | 1,784 ms |
| コンパイル使用メモリ | 141,444 KB |
| 最終ジャッジ日時 | 2025-01-10 05:47:11 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 12 |
ソースコード
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <cassert>
#include <fstream>
#include <utility>
#include <functional>
#include <time.h>
#include <stack>
#include <array>
#define popcount __builtin_popcount
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
vector< int > manacher(const string &s) {
int n=s.size();
vector< int > radius(n);
int i = 0, j = 0;
while(i < n) {
while(i - j >= 0 && i + j < n && s[i - j] == s[i + j]) {
++j;
}
radius[i] = j;
int k = 1;
while(i - k >= 0 && i + k < n && k + radius[i - k] < j) {
radius[i + k] = radius[i - k];
++k;
}
i += k;
j -= k;
}
return radius;
}
template<ll mod>
struct RollingHash{
vector<ll> hash, power;
RollingHash(const string &s, ll base=10007){
int sz=s.size();
hash.resize(sz+1);
power.resize(sz+1);
power[0]=1;
for(int i=0; i<sz; i++){
power[i+1]=power[i]*base%mod;
hash[i+1]=(hash[i]*base+s[i])%mod;
}
}
ll get(int l, int r) const{ // [l, r)
ll ret=hash[r]-hash[l]*power[r-l]%mod+mod;
if(ret>=mod) ret-=mod;
return ret;
}
ll concat(ll h1, ll h2, int len2) const{ //h1+h2
ll ret=h1*power[len2]%mod+h2;
if(ret>=mod) ret-=mod;
return ret;
}
};
int main()
{
string s[2];
cin>>s[0]>>s[1];
unordered_map<ll, ll> mps[2];
for(int z=0; z<2; z++){
int n=s[z].size();
string s1="#";
for(int i=0; i<n; i++){
s1+=s[z][i], s1+='#';
}
auto vs=manacher(s[z]), vs1=manacher(s1);
const ll MOD1=1e9+7;
const ll MOD2=1e9+9;
RollingHash<MOD1> rs1(s[z]);
RollingHash<MOD2> rs2(s[z]);
vector<vector<pair<int, ll>>> ss(n+1);
for(int i=0; i<n; i++){
int l=i-vs[i]+1, r=i+vs[i];
ll x=(rs1.get(l, r)<<30)^rs2.get(l, r);
if(mps[z].find(x)==mps[z].end()) ss[r-l].push_back({l, x});
mps[z][x]++;
if(i==n-1) break;
int u=(vs1[(i<<1)+2]>>1);
if(u==0) continue;
l=i-u+1, r=i+1+u;
x=(rs1.get(l, r)<<30)^rs2.get(l, r);
if(mps[z].find(x)==mps[z].end()) ss[r-l].push_back({l, x});
mps[z][x]++;
}
for(int d=n; d>=3; d--){
for(auto p:ss[d]){
int l=p.first; ll x0=p.second;
ll x=(rs1.get(l+1, l+d-1)<<30)^rs2.get(l+1, l+d-1);
if(mps[z].find(x)==mps[z].end()) ss[d-2].push_back({l+1, x});
mps[z][x]+=mps[z][x0];
}
}
}
ll ans=0;
for(auto p:mps[0]){
ll x=p.first;
if(mps[1].find(x)!=mps[1].end()){
ans+=mps[1][x]*p.second;
}
}
cout<<ans<<endl;
return 0;
}
chocorusk