Submission #283600

# Submission time Handle Problem Language Result Execution time Memory
283600 2020-08-26T02:28:15 Z rrrr10000 Palindromes (APIO14_palindrome) C++14
23 / 100
849 ms 46108 KB
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n)  for(long long i=0;i<(long long)(n);i++)
#define REP(i,k,n) for(long long i=k;i<(long long)(n);i++)
#define all(a) a.begin(),a.end()
#define pb emplace_back
#define eb emplace_back
#define lb(v,k) (lower_bound(all(v),k)-v.begin())
#define ub(v,k) (upper_bound(all(v),k)-v.begin())
#define fi first
#define se second
#define pi M_PI
#define PQ(T) priority_queue<T>
#define SPQ(T) priority_queue<T,vector<T>,greater<T>>
#define dame(a) {out(a);return 0;}
#define decimal cout<<fixed<<setprecision(15);
#define dupli(a) {sort(all(a));a.erase(unique(all(a)),a.end());}
typedef long long ll;
typedef pair<ll,ll> P;
typedef tuple<ll,ll,ll> PP;
typedef tuple<ll,ll,ll,ll> PPP;
typedef multiset<ll> S;
using vi=vector<ll>;
using vvi=vector<vi>;
using vvvi=vector<vvi>;
using vvvvi=vector<vvvi>;
using vp=vector<P>;
using vvp=vector<vp>;
using vb=vector<bool>;
using vvb=vector<vb>;
const ll inf=1001001001001001001;
const ll INF=1001001001;
const ll mod=1000000007;
const double eps=1e-10;
template<class T> bool chmin(T&a,T b){if(a>b){a=b;return true;}return false;}
template<class T> bool chmax(T&a,T b){if(a<b){a=b;return true;}return false;}
template<class T> void out(T a){cout<<a<<'\n';}
template<class T> void outp(T a){cout<<'('<<a.fi<<','<<a.se<<')'<<'\n';}
template<class T> void outvp(T v){rep(i,v.size())cout<<'('<<v[i].fi<<','<<v[i].se<<')';cout<<'\n';}
template<class T> void outvvp(T v){rep(i,v.size())outvp(v[i]);}
template<class T> void outv(T v){rep(i,v.size()){if(i)cout<<' ';cout<<v[i];}cout<<'\n';}
template<class T> void outvv(T v){rep(i,v.size())outv(v[i]);}
template<class T> bool isin(T x,T l,T r){return (l)<=(x)&&(x)<=(r);}
template<class T> void yesno(T b){if(b)out("yes");else out("no");}
template<class T> void YesNo(T b){if(b)out("Yes");else out("No");}
template<class T> void YESNO(T b){if(b)out("YES");else out("NO");}
template<class T> void noyes(T b){if(b)out("no");else out("yes");}
template<class T> void NoYes(T b){if(b)out("No");else out("Yes");}
template<class T> void NOYES(T b){if(b)out("NO");else out("YES");}
void outs(ll a,ll b){if(a>=inf-100)out(b);else out(a);}
ll gcd(ll a,ll b){if(b==0)return a;return gcd(b,a%b);}
ll modpow(ll a,ll b){ll res=1;a%=mod;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;}
 
vi manacher(string &s){
    int i=0,j=0;
    vi res(s.size());
    while(i<s.size()){
        while(i-j>=0&&i+j<s.size()&&s[i-j]==s[i+j])j++;
        res[i]=j;
        int k=1;
        while(i-k>=0&&k+res[i-k]<j){
            res[i+k]=res[i-k];
            k++;
        }
        i+=k;j-=k;
    }
    return res;
}
 
vi SA_IS(vi str, int var) {
    if(str.size() == 1) {
        vi ret(1,0);
        return ret;
    }
    str.push_back(0);
    int si = str.size();
    vi st(var, 0), en(var, 0);
    vi SL(si, 0); //s..0, l..1
    vi SA(si, -1);
    vi LMS;
    vi is_LMS(si, -1);
    rep(i,str.size()) en[str[i]]++;
    for(int i = 1; i < var; i++) en[i] += en[i-1];
    for(int i = 1; i < var; i++) st[i] = en[i-1];
    SL[str.size()-1] = 0;
    for(int i = str.size()-2; i >= 0; i--) {
        if(str[i] == str[i+1]) {
            SL[i] = SL[i+1];
            continue;
        }
        if(str[i] > str[i+1]) SL[i] = 1;
        else SL[i] = 0;
    }
    for(int i = 1; i < str.size(); i++) {
        if(SL[i] == 0 && SL[i-1] == 1) {
            SA[--en[str[i]]] = i;
            LMS.push_back(i);
            is_LMS[i] = 1;
        }
    }
    rep(i,var-1) en[i] = st[i+1];
    en[var-1] = str.size();
    
    rep(i,str.size()) if(SA[i] > 0 && SL[SA[i]-1] == 1) { SA[st[str[SA[i]-1]]++] = SA[i]-1; }
    st[0] = 0;
    for(int i = 1; i < var; i++) st[i] = en[i-1];
    
    for(int i = 1; i < str.size(); i++) if(SA[i] != -1 && SL[SA[i]] == 0) { SA[i] = -1; }
    
    for(int i = str.size()-1; i >= 1; i--) if(SA[i] > 0 && SL[SA[i]-1] == 0) { SA[--en[str[SA[i]-1]]] = SA[i]-1; }
    rep(i,var-1) en[i] = st[i+1];
    en[var-1] = str.size();
    
    int counter = 0;
    vi pre_sa, new_sa;
    rep(i,SA.size()) if(is_LMS[SA[i]] != -1) {
        is_LMS[SA[i]] = ++counter; 
        
        new_sa.clear();
        for(int j = SA[i]; j < SA.size(); j++) {
            new_sa.push_back(str[j]);
            if(j != SA[i] && is_LMS[j] != -1) {
                break;
            }
        }
        if(pre_sa == new_sa) {
            is_LMS[SA[i]] = --counter;
        }
        pre_sa = new_sa;
    }
    
    vi new_str;
    vi rev((int)LMS.size()+1, 0);
    counter = 0;
    rep(i,is_LMS.size()) {
        if(is_LMS[i] != -1) {
            new_str.push_back(is_LMS[i]);
            rev[counter++] = i;
        }
    }
    vi rec = SA_IS(new_str, new_str.size()+1);
    
    rep(i,SA.size()) SA[i] = -1;
    
    for(int i = rec.size()-1; i >= 0; i--) { SA[--en[str[rev[rec[i]]]]] = rev[rec[i]]; }
    rep(i,var-1) en[i] = st[i+1];
    en[var-1] = str.size();
    
    rep(i,str.size()) if(SA[i] > 0 && SL[SA[i]-1] == 1) { SA[st[str[SA[i]-1]]++] = SA[i]-1; }
    
    for(int i = 1; i < str.size(); i++) if(SA[i] != -1 && SL[SA[i]] == 0) { SA[i] = -1; }
    
    for(int i = str.size()-1; i >= 1; i--) if(SA[i] > 0 && SL[SA[i]-1] == 0) { SA[--en[str[SA[i]-1]]] = SA[i]-1; }
    
    SA.erase(SA.begin());
    return SA;
}
int main(){
    string s;cin>>s;
    string t;
    rep(i,s.size()){
        if(i)t+='x';
        t+=s[i];
    }
    vi m=manacher(t);
    vp q;
    rep(i,m.size()){
        if(i&1)q.pb(i/2-m[i]/2+1,i/2+m[i]/2);
        else q.pb(i/2-(m[i]-1)/2,i/2+(m[i]-1)/2);
    }
    ll n=s.size();
    vi has(n+1);
    rep(i,n)has[i+1]=(has[i]*937+(s[i]-'a'+1));
    vi str(n);
    rep(i,n)str[i]=s[i]-'a'+1;
    vi sa=SA_IS(str,30);
    sa.insert(sa.begin(),n);
    vi rs(n+1);
    rep(i,n+1)rs[sa[i]]=i;
    ll ans=0;
    vi mp(n+5);
    mp[0]=1;
    rep(i,n+4)mp[i+1]=mp[i]*937;
    // outvp(q);outv(sa);outv(rs);outv(has);
    for(auto x:q){
        ll len=x.se-x.fi+1;
        ll to=rs[x.fi],ng=n+1;
        while(ng-to>1){
            ll md=(to+ng)/2;
            ll id=sa[md];
            if(id+len>n){ng=md;continue;}
            ll a=(has[x.se+1]-has[x.fi]*mp[len]);
            ll b=(has[id+len]-has[id]*mp[len]);
            if(a==b)to=md;
            else ng=md;
        }
        ll fr=rs[x.fi],ngg=0;
        while(fr-ngg>1){
            ll md=(fr+ngg)/2;
            ll id=sa[md];
            if(id+len>n){ngg=md;continue;}
            ll a=(has[x.se+1]-has[x.fi]*mp[len]);
            ll b=(has[id+len]-has[id]*mp[len]);
            if(a==b)fr=md;
            else ngg=md;
        }
        // if(x==P(0,2))outp(P(to,fr));
        chmax(ans,(to-fr+1)*len);
    }
    out(ans);
}

Compilation message

palindrome.cpp: In function 'vi manacher(std::string&)':
palindrome.cpp:60:12: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   60 |     while(i<s.size()){
      |           ~^~~~~~~~~
palindrome.cpp:61:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   61 |         while(i-j>=0&&i+j<s.size()&&s[i-j]==s[i+j])j++;
      |                       ~~~^~~~~~~~~
palindrome.cpp: In function 'vi SA_IS(vi, int)':
palindrome.cpp:97:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   97 |     for(int i = 1; i < str.size(); i++) {
      |                    ~~^~~~~~~~~~~~
palindrome.cpp:111:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  111 |     for(int i = 1; i < str.size(); i++) if(SA[i] != -1 && SL[SA[i]] == 0) { SA[i] = -1; }
      |                    ~~^~~~~~~~~~~~
palindrome.cpp:123:30: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  123 |         for(int j = SA[i]; j < SA.size(); j++) {
      |                            ~~^~~~~~~~~~~
palindrome.cpp:154:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  154 |     for(int i = 1; i < str.size(); i++) if(SA[i] != -1 && SL[SA[i]] == 0) { SA[i] = -1; }
      |                    ~~^~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 1 ms 256 KB Output is correct
2 Correct 0 ms 256 KB Output is correct
3 Correct 0 ms 256 KB Output is correct
4 Correct 1 ms 256 KB Output is correct
5 Correct 0 ms 256 KB Output is correct
6 Correct 0 ms 256 KB Output is correct
7 Correct 1 ms 256 KB Output is correct
8 Correct 0 ms 256 KB Output is correct
9 Correct 0 ms 256 KB Output is correct
10 Correct 0 ms 256 KB Output is correct
11 Correct 0 ms 256 KB Output is correct
12 Correct 1 ms 256 KB Output is correct
13 Correct 0 ms 256 KB Output is correct
14 Correct 0 ms 256 KB Output is correct
15 Correct 0 ms 256 KB Output is correct
16 Correct 0 ms 256 KB Output is correct
17 Correct 1 ms 256 KB Output is correct
18 Correct 0 ms 256 KB Output is correct
19 Correct 1 ms 256 KB Output is correct
20 Correct 1 ms 256 KB Output is correct
21 Correct 1 ms 256 KB Output is correct
22 Correct 0 ms 384 KB Output is correct
23 Correct 0 ms 384 KB Output is correct
24 Correct 0 ms 384 KB Output is correct
25 Correct 0 ms 384 KB Output is correct
26 Correct 0 ms 384 KB Output is correct
27 Correct 0 ms 384 KB Output is correct
28 Correct 0 ms 256 KB Output is correct
29 Correct 0 ms 384 KB Output is correct
30 Correct 0 ms 384 KB Output is correct
31 Correct 1 ms 384 KB Output is correct
32 Correct 0 ms 384 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 512 KB Output is correct
2 Correct 1 ms 512 KB Output is correct
3 Correct 1 ms 384 KB Output is correct
4 Correct 1 ms 512 KB Output is correct
5 Correct 1 ms 384 KB Output is correct
6 Correct 1 ms 384 KB Output is correct
7 Correct 2 ms 512 KB Output is correct
8 Correct 1 ms 512 KB Output is correct
9 Correct 1 ms 512 KB Output is correct
10 Correct 1 ms 384 KB Output is correct
11 Correct 1 ms 512 KB Output is correct
12 Correct 1 ms 512 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 6 ms 1656 KB Output is correct
2 Correct 6 ms 1784 KB Output is correct
3 Correct 5 ms 1400 KB Output is correct
4 Correct 5 ms 1272 KB Output is correct
5 Correct 9 ms 1912 KB Output is correct
6 Correct 8 ms 1784 KB Output is correct
7 Correct 6 ms 1784 KB Output is correct
8 Correct 9 ms 1656 KB Output is correct
9 Correct 10 ms 1656 KB Output is correct
10 Incorrect 9 ms 1656 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 73 ms 14060 KB Output is correct
2 Correct 91 ms 14820 KB Output is correct
3 Correct 48 ms 10092 KB Output is correct
4 Correct 61 ms 10976 KB Output is correct
5 Correct 167 ms 13032 KB Output is correct
6 Correct 154 ms 15468 KB Output is correct
7 Correct 102 ms 12140 KB Output is correct
8 Correct 188 ms 13540 KB Output is correct
9 Correct 147 ms 13292 KB Output is correct
10 Incorrect 170 ms 13924 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 267 ms 43296 KB Output is correct
2 Correct 348 ms 43292 KB Output is correct
3 Correct 151 ms 31816 KB Output is correct
4 Correct 194 ms 32828 KB Output is correct
5 Correct 800 ms 46108 KB Output is correct
6 Correct 412 ms 39492 KB Output is correct
7 Correct 399 ms 38944 KB Output is correct
8 Correct 835 ms 40740 KB Output is correct
9 Correct 849 ms 40480 KB Output is correct
10 Incorrect 788 ms 41628 KB Output isn't correct
11 Halted 0 ms 0 KB -