제출 #46105

#제출 시각아이디문제언어결과실행 시간메모리
46105Extazy회문 (APIO14_palindrome)C++17
73 / 100
1086 ms43212 KiB
#include <bits/stdc++.h> #define endl '\n' using namespace std; const unsigned long long B1 = 131, B2 = 137, MOD = (1e9) + 7; const int N = 300007; struct rolling_hash { unsigned long long h1,h2; rolling_hash(): h1(0), h2(0) {} void append(char a) { h1*=B1; h1+=a-'a'+1; h2*=B2; h2+=a-'a'+1; h2%=MOD; } bool operator ==(const rolling_hash &a) const { return h1==a.h1 && h2==a.h2; } bool operator <(const rolling_hash &a) const { return h1==a.h1 ? h2<a.h2 : h1<a.h1; } }; struct item { rolling_hash hash; int from,to; item(){} item(rolling_hash a, int b, int c): hash(a), from(b), to(c) {} bool operator <(const item &a) const { return to-from+1==a.to-a.from+1 ? hash<a.hash : to-from+1>a.to-a.from+1; } }; int n; char a[N]; unsigned long long pw1[N],pw2[N]; rolling_hash ph[N],sh[N]; map < rolling_hash, pair < int, int > > interval; map < rolling_hash, int > current_cnt; set < item > s; long long ans; rolling_hash get_prefix_hash(rolling_hash *a, int l, int r) { rolling_hash hl=a[l-1],hr=a[r]; hl.h1*=pw1[r-l+1]; hl.h2*=pw2[r-l+1]; hl.h2%=MOD; hr.h1-=hl.h1; hr.h2-=hl.h2; hr.h2+=MOD; hr.h2%=MOD; return hr; } rolling_hash get_suffix_hash(rolling_hash *a, int l, int r) { rolling_hash hl=a[l],hr=a[r+1]; hr.h1*=pw1[r-l+1]; hr.h2*=pw2[r-l+1]; hr.h2%=MOD; hl.h1-=hr.h1; hl.h2-=hr.h2; hl.h2+=MOD; hl.h2%=MOD; return hl; } bool is_palindrome(int l, int r) { return get_prefix_hash(ph,l,r)==get_suffix_hash(sh,l,r); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int i,j; rolling_hash h; pw1[0]=pw2[0]=1; for(i=1;i<N;i++) { pw1[i]=pw1[i-1]*B1; pw2[i]=pw2[i-1]*B2%MOD; } scanf("%s", a+1); n=strlen(a+1); h=rolling_hash(); for(i=1;i<=n;i++) { h.append(a[i]); ph[i]=h; } h=rolling_hash(); for(i=n;i>=1;i--) { h.append(a[i]); sh[i]=h; } for(i=1;i<=n;i++) { int left=0,right=min(i,n-i+1),middle; while(right-left>1) { middle=(left+right)/2; if(is_palindrome(i-middle,i+middle)) left=middle; else right=middle; } for(j=left;j>=0;j--) { h=get_prefix_hash(ph,i-j,i+j); if(interval.find(h)!=interval.end()) break; interval[h]=make_pair(i-j,i+j); } h=get_prefix_hash(ph,i-left,i+left); ++current_cnt[h]; } for(i=1;i<n;i++) if(a[i]==a[i+1]) { int left=0,right=min(i,n-i),middle; while(right-left>1) { middle=(left+right)/2; if(is_palindrome(i-middle,i+1+middle)) left=middle; else right=middle; } for(j=left;j>=0;j--) { h=get_prefix_hash(ph,i-j,i+1+j); if(interval.find(h)!=interval.end()) break; interval[h]=make_pair(i-j,i+1+j); } h=get_prefix_hash(ph,i-left,i+1+left); ++current_cnt[h]; } for(map < rolling_hash, int >::iterator it=current_cnt.begin();it!=current_cnt.end();it++) { h=it->first; pair < int, int > seg=interval[h]; s.insert(item(h,seg.first,seg.second)); } while(!s.empty()) { item curr=*s.begin(); s.erase(s.begin()); int cnt=current_cnt[curr.hash]; ans=max(ans,cnt*1ll*(curr.to-curr.from+1)); if(curr.to-curr.from+1>2) { curr.hash=get_prefix_hash(ph,curr.from+1,curr.to-1); pair < int, int > seg=interval[curr.hash]; curr.from=seg.first; curr.to=seg.second; current_cnt[curr.hash]+=cnt; s.insert(curr); } } printf("%lld\n", ans); return 0; }

컴파일 시 표준 에러 (stderr) 메시지

palindrome.cpp: In function 'int main()':
palindrome.cpp:98:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%s", a+1);
     ~~~~~^~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...