結果
| 問題 |
No.263 Common Palindromes Extra
|
| コンテスト | |
| ユーザー |
chocorusk
|
| 提出日時 | 2020-05-04 10:40:53 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,987 ms / 2,000 ms |
| コード長 | 2,927 bytes |
| コンパイル時間 | 2,219 ms |
| コンパイル使用メモリ | 140,928 KB |
| 最終ジャッジ日時 | 2025-01-10 06:22:29 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| 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;
}
struct RollingHash{
using ull=unsigned long long;
const ull mask30=(1ll<<30)-1;
const ull mask31=(1ll<<31)-1;
const ull mod=(1ll<<61)-1;
const ull positivizer=(mod<<2);
ull calcmod(ull x){
ull ret=(x>>61)+(x&mod);
if(ret>=mod) ret-=mod;
return ret;
}
ull mul(ull a, ull b){
ull au=(a>>31), ad=(a&mask31), bu=(b>>31), bd=(b&mask31);
ull mid=au*bd+ad*bu;
ull midu=(mid>>30), midd=(mid&mask30);
ull ret=((au*bu)<<1)+midu+(midd<<31)+ad*bd; //ret<2^63
return ret;
}
vector<ull> hash, power;
RollingHash(const string &s, ull base=1000000007){
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]=calcmod(mul(power[i], base));
hash[i+1]=calcmod(mul(hash[i], base)+s[i]);
}
}
ull get(int l, int r){ // [l, r)
return calcmod(hash[r]+positivizer-mul(hash[l], power[r-l]));
}
ull concat(ll h1, ll h2, int len2){ //h1+h2
return calcmod(mul(h1, power[len2])+h2);
}
};
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(s1);
RollingHash rs(s[z]);
vector<vector<pair<int, ll>>> ss(n+1);
for(int i=0; i<n; i++){
int u=(vs[(i<<1)^1]>>1);
int l=i-u+1, r=i+u;
ll x=rs.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;
u=(vs[(i<<1)+2]>>1);
if(u==0) continue;
l=i-u+1, r=i+1+u;
x=rs.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=rs.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