結果
問題 | No.465 PPPPPPPPPPPPPPPPAPPPPPPPP |
ユーザー |
![]() |
提出日時 | 2016-12-16 23:23:40 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 128 ms / 2,000 ms |
コード長 | 3,616 bytes |
コンパイル時間 | 1,481 ms |
コンパイル使用メモリ | 166,004 KB |
実行使用メモリ | 20,864 KB |
最終ジャッジ日時 | 2024-11-30 21:51:49 |
合計ジャッジ時間 | 3,374 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 20 |
コンパイルメッセージ
main.cpp: In function ‘int main()’: main.cpp:50:8: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 50 | scanf("%s",s); | ~~~~~^~~~~~~~
ソースコード
#include <bits/stdc++.h>using namespace std;typedef long long ll;typedef vector<int> vi;typedef vector<ll> vl;typedef pair<int,int> pii;typedef pair<ll,ll> pll;typedef int _loop_int;#define REP(i,n) for(_loop_int i=0;i<(_loop_int)(n);++i)#define FOR(i,a,b) for(_loop_int i=(_loop_int)(a);i<(_loop_int)(b);++i)#define FORR(i,a,b) for(_loop_int i=(_loop_int)(b)-1;i>=(_loop_int)(a);--i)#define DEBUG(x) cout<<#x<<": "<<x<<endl#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl#define ALL(a) (a).begin(),(a).end()#define CHMIN(a,b) a=min((a),(b))#define CHMAX(a,b) a=max((a),(b))// modconst ll MOD = 1000000007ll;#define FIX(a) ((a)%MOD+MOD)%MOD// floatingtypedef double Real;const Real EPS = 1e-11;#define EQ0(x) (abs(x)<EPS)#define EQ(a,b) (abs(a-b)<EPS)typedef complex<Real> P;int n;char s[525252];// manacherint m;char ss[1252525];int mana[1252525];ll tailpal[525252];inline bool pal(int l,int r){return mana[r+l-1] > r-l-1;}ll pl[525252];ll gpl[525252];int main(){scanf("%s",s);n = strlen(s);for(int i=0;i<n;i++){ss[2*i] = s[i];ss[2*i+1] = '$';}m = 2*n-1;// manacher{int i=0,j=0;while(i<m){while(i-j>=0 && i+j<m && ss[i-j]==ss[i+j])j++;mana[i] = j;int k=1;while(i-k>=0 && i+k<m && k+mana[i-k]<j){mana[i+k] = mana[i-k];k++;}i += k;j -= k;}}for(int i=n-1;i>0;i--){tailpal[i-1] = tailpal[i] + (mana[n+i-1]>n-i-1);}// 解説を読みました……><// https://arxiv.org/pdf/1403.2431v2.pdf// pp.11typedef pair<int,pii> trip;#define X first#define Y second.first#define Z second.second#define PACK(x,y,z) trip(x,pii(y,z))#define UNPACK(x,y,z,t) int x=(t).X,y=(t).Y,z=(t).Zvector<trip> G,G2;FOR(j,1,n+1){G2.clear();for(auto T:G){UNPACK(x,y,z,T);// palindromeif(x>1 && s[x-2]==s[j-1]){G2.push_back(PACK(x-1,y,z));}}swap(G,G2);G2.clear();int r = -j;for(auto T:G){UNPACK(x,y,z,T);if(x-r != y){G2.push_back(PACK(x,x-r,1));if(z>1){G2.push_back(PACK(x+y,y,z-1));}}else{G2.push_back(T);}r = x + (z-1)*y;}if(j>1 && s[j-2]==s[j-1]){G2.push_back(PACK(j-1,j-1-r,1));r = j-1;}G2.push_back(PACK(j,j-r,1));G.clear();auto fst = G2[0];UNPACK(xx,yy,zz,fst);bool flag = true;for(auto T:G2){if(flag){flag=false;continue;}UNPACK(x,y,z,T);if(y==yy){zz += z;}else{G.push_back(PACK(xx,yy,zz));xx = x;yy = y;zz = z;}}G.push_back(PACK(xx,yy,zz));// modify for split palindrome// 元 : prefixを最小のpalindromeで構成する 数:pl[i]// 新 : PPと分解する数// 周期性のあるpalindromeで表せるため計算が使いまわせる、らしい// pl[j] = j;pl[j-1] = 0;for(auto T:G){UNPACK(x,y,z,T);r = x + (z-1)*y;// int mm = pl[r-1]+1;// 最小周期でPPと分割ll mm = 0;if(r>=2 && pal(0,r-2+1))mm = 1;// 周期1つ戻した計算結果を再利用if(z>1){// CHMIN(mm,gpl[x-z]);mm += gpl[x-y];}// メモif(y<=x){gpl[x-y] = mm;}// CHMIN(pl[j],mm);pl[j-1] += mm;}}ll ans = 0;FOR(i,1,n-1){ans += pl[i] * tailpal[i+1];}printf("%lld\n",ans);// 難しい><return 0;}