結果

問題 No.2162 Copy and Paste 2
ユーザー tko919tko919
提出日時 2022-12-13 01:51:24
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 1,791 ms / 7,000 ms
コード長 9,563 bytes
コンパイル時間 2,950 ms
コンパイル使用メモリ 222,720 KB
実行使用メモリ 41,452 KB
最終ジャッジ日時 2024-04-24 14:39:41
合計ジャッジ時間 25,639 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 2 ms
5,376 KB
testcase_04 AC 2 ms
5,376 KB
testcase_05 AC 2 ms
5,376 KB
testcase_06 AC 230 ms
26,724 KB
testcase_07 AC 244 ms
26,856 KB
testcase_08 AC 532 ms
26,732 KB
testcase_09 AC 433 ms
26,848 KB
testcase_10 AC 438 ms
26,724 KB
testcase_11 AC 575 ms
26,728 KB
testcase_12 AC 602 ms
26,724 KB
testcase_13 AC 897 ms
26,732 KB
testcase_14 AC 482 ms
26,728 KB
testcase_15 AC 505 ms
26,460 KB
testcase_16 AC 517 ms
26,856 KB
testcase_17 AC 1,278 ms
26,604 KB
testcase_18 AC 1,504 ms
27,880 KB
testcase_19 AC 1,485 ms
27,496 KB
testcase_20 AC 1,466 ms
26,984 KB
testcase_21 AC 730 ms
26,604 KB
testcase_22 AC 715 ms
26,592 KB
testcase_23 AC 164 ms
26,616 KB
testcase_24 AC 1,743 ms
41,448 KB
testcase_25 AC 1,791 ms
41,444 KB
testcase_26 AC 1,648 ms
30,568 KB
testcase_27 AC 1,748 ms
41,452 KB
testcase_28 AC 1,580 ms
31,208 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define ALL(v) (v).begin(),(v).end()
using ll=long long int;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;
template<typename T>inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<typename T>inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>

class FastIO{
    static constexpr int L=1<<16;
    char rdbuf[L];
    int rdLeft=0,rdRight=0;
    inline void reload(){
        int len=rdRight-rdLeft;
        memmove(rdbuf,rdbuf+rdLeft,len);
        rdLeft=0,rdRight=len;
        rdRight+=fread(rdbuf+len,1,L-len,stdin);
    }
    inline bool skip(){
        for(;;){
            while(rdLeft!=rdRight and rdbuf[rdLeft]<=' ')rdLeft++;
            if(rdLeft==rdRight){
                reload();
                if(rdLeft==rdRight)return false;
            }
            else break;
        }
        return true;
    }
    template<typename T,enable_if_t<is_integral<T>::value,int> =0>inline bool _read(T& x){
        if(!skip())return false;
        if(rdLeft+20>=rdRight)reload();
        bool neg=false;
        if(rdbuf[rdLeft]=='-'){
            neg=true;
            rdLeft++;
        }
        x=0;
        while(rdbuf[rdLeft]>='0' and rdLeft<rdRight){
            x=x*10+(neg?-(rdbuf[rdLeft++]^48):(rdbuf[rdLeft++]^48));
        }
        return true;
    }
    template<typename T,enable_if_t<is_floating_point<T>::value,int> =0>inline bool _read(T& x){
        if(!skip())return false;
        if(rdLeft+20>=rdRight)reload();
        bool neg=false;
        if(rdbuf[rdLeft]=='-'){
            neg=true;
            rdLeft++;
        }
        x=0;
        while(rdbuf[rdLeft]>='0' and rdbuf[rdLeft]<='9' and rdLeft<rdRight){
            x=x*10+(rdbuf[rdLeft++]^48);
        }
        if(rdbuf[rdLeft]!='.')return true;
        rdLeft++;
        T base=.1;
        while(rdbuf[rdLeft]>='0' and rdbuf[rdLeft]<='9' and rdLeft<rdRight){
            x+=base*(rdbuf[rdLeft++]^48);
            base*=.1;
        }
        if(neg)x=-x;
        return true;
    }
    inline bool _read(char& x){
        if(!skip())return false;
        if(rdLeft+1>=rdRight)reload();
        x=rdbuf[rdLeft++];
        return true;
    }
    inline bool _read(string& x){
        if(!skip())return false;
        for(;;){
            int pos=rdLeft;
            while(pos<rdRight and rdbuf[pos]>' ')pos++;
            x.append(rdbuf+rdLeft,pos-rdLeft);
            if(rdLeft==pos)break;
            rdLeft=pos;
            if(rdLeft==rdRight)reload();
            else break;
        }
        return true;
    }
    template<typename T>inline bool _read(vector<T>& v){
        for(auto& x:v){
            if(!_read(x))return false;
        }
        return true;
    }

    char wtbuf[L],tmp[50];
    int wtRight=0;
    inline void flush(){
        fwrite(wtbuf,1,wtRight,stdout);
        wtRight=0;
    }
    inline void _write(const char& x){
        if(wtRight>L-32)flush();
        wtbuf[wtRight++]=x;
    }
    inline void _write(const string& x){
        for(auto& c:x)_write(c);
    }
    template<typename T,enable_if_t<is_integral<T>::value,int> =0>inline void _write(T x){
        if(wtRight>L-32)flush();
        if(x==0){
            _write('0');
            return;
        }
        else if(x<0){
            _write('-');
            if (__builtin_expect(x == std::numeric_limits<T>::min(), 0)) {
                switch (sizeof(x)) {
                case 2: _write("32768"); return;
                case 4: _write("2147483648"); return;
                case 8: _write("9223372036854775808"); return;
                }
            }
            x=-x;
        }
        int pos=0;
        while(x!=0){
            tmp[pos++]=char((x%10)|48);
            x/=10;
        }
        rep(i,0,pos)wtbuf[wtRight+i]=tmp[pos-1-i];
        wtRight+=pos;
    }
    template<typename T>inline void _write(const vector<T>& v){
        rep(i,0,v.size()){
            if(i)_write(' ');
            _write(v[i]);
        }
    }
public:
    FastIO(){}
    ~FastIO(){flush();}
    inline void read(){}
    template <typename Head, typename... Tail>inline void read(Head& head,Tail&... tail){
        assert(_read(head));
        read(tail...); 
    }
    template<bool ln=true,bool space=false>inline void write(){if(ln)_write('\n');}
    template <bool ln=true,bool space=false,typename Head, typename... Tail>inline void write(const Head& head,const Tail&... tail){
        if(space)_write(' ');
        _write(head);
        write<ln,true>(tail...); 
    }
};

/**
 * @brief Fast IO
 */
#line 3 "sol.cpp"

#line 2 "library/String/zalgo.hpp"

template<typename T>vector<int> Zalgo(T& s){
   int n=s.size(); vector<int> res(n);
   for(int i=1,j=0;i<n;i++){
      if(i+res[i-j]<j+res[j])res[i]=res[i-j];
      else{
         int k=max(0,j+res[j]-i);
         while(i+k<n&&s[k]==s[i+k])k++;
         res[i]=k; j=i;
      }
   } res[0]=n; return res;
}

/**
 * @brief Z-Algorithm
 */
#line 5 "sol.cpp"

#line 2 "library/DataStructure/lichaotree.hpp"

template<typename T,T MX>struct CHT{
    using Line=pair<T,T>;
    int n;
    vector<T> xs;
    vector<Line> ls;
    CHT(vector<T>& ps):xs(ps){
        n=1;
        while(n<(int)xs.size())n<<=1;
        xs.resize(n,xs.back());
        ls.resize(2*n-1,Line(0,MX));
    }
    T eval(Line& f,T x){return f.first*x+f.second;}
    void add(T a,T b,int k=0,int L=0,int R=-1){
        if(R==-1)R=n;
        Line f={a,b};
        while(L!=R){
            int mid=(L+R)>>1;
            T lx=xs[L],mx=xs[mid],rx=xs[R-1];
            Line& g=ls[k];
            if(eval(f,lx)<eval(g,lx) and eval(f,rx)<eval(g,rx)){
                g=f;
                return;
            }
            if(eval(f,lx)>=eval(g,lx) and eval(f,rx)>=eval(g,rx))return;
            if(eval(f,mx)<eval(g,mx))swap(f,g);
            if(eval(f,lx)<eval(g,lx)){
                k=k*2+1;
                R=mid;
            }
            else{
                k=k*2+2;
                L=mid;
            }
        }
    }
    void add_segment(T a,T b,T L,T R){
        int l=lower_bound(ALL(xs),L)-xs.begin(),r=lower_bound(ALL(xs),R)-xs.begin();
        int a0=l,b0=r;
        l+=n,r+=n;
        int sz=1;
        while(l<r){
            if(r&1){
                r--;
                b0-=sz;
                add(a,b,r-1,b0,b0+sz);
            }
            if(l&1){
                add(a,b,l-1,a0,a0+sz);
                l++;
                a0+=sz;
            }
            l>>=1;
            r>>=1;
            sz<<=1;
        }
    }
    T getmin(T x){
        int k=lower_bound(ALL(xs),x)-xs.begin()+n-1;
        T res=eval(ls[k],x);
        while(k){
            k=(k-1)>>1;
            chmin(res,eval(ls[k],x));
        }
        return res;
    }
};

/**
 * @brief Convex Hull Trick (Li Chao Tree)
 * @docs docs/lichaotree.md
 */
#line 7 "sol.cpp"

int naive(string& s){
    int n=s.size();
    auto seq=Zalgo(s);

    vector dp(n+1,vector<int>(n+1,inf));
    dp[0][0]=0;
    rep(i,0,n)rep(j,0,i+1){
        // add
        chmin(dp[i+1][j],dp[i][j]+1);
        // copy
        chmin(dp[i][i],dp[i][j]+1);
        // paste
        if(i!=n-1 and seq[i+1]>=j+1)chmin(dp[i+j+1][j],dp[i][j]+1);
    }
    int ret=inf;
    rep(j,0,n+1)chmin(ret,dp[n][j]);
    return ret;
}

#line 2 "library/Utility/random.hpp"

struct Random{
    random_device rnd;
    unsigned x=123456789,y=362436069,z=521288629,w=rnd();
    Random(){}
    unsigned get(){
        unsigned t=x^(x<<11);
        x=y,y=z,z=w;
        return w=(w^(w<<19))^(t^(t>>8));
    }
    unsigned get(unsigned L){
        return get()%(L+1);
    }
    template<typename T>T get(T L,T R){
        return get(R-L)+L;
    }
    double uniform(){
        return double(get())/UINT_MAX;
    }
    string str(int n){
        string ret;
        rep(i,0,n)ret+=get('a','z');
        return ret;
    }
    template<typename Iter>void shuffle(Iter first,Iter last){
        if(first==last)return;
        int len=1;
        for(auto it=first+1;it!=last;it++){
            len++;
            int j=get(0,len-1);
            if(j!=len-1)iter_swap(it,first+j);
        }
    }
    template<typename T>vector<T> select(int n,T L,T R){
        set<T> ret;
        while(ret.size()<n)ret.insert(get(L,R));
        return {ALL(ret)};
    }
};

/**
 * @brief Random
 */
#line 28 "sol.cpp"
Random gen;

FastIO io;
int main(){
    // for(;;){
    string s;
    io.read(s);
    // rep(_,0,gen.get(20,30)){
    //     if(gen.get(0,1))s+='a';
    //     else s+='b';
    // }

    int n=s.size();
    vector<int> tmp(n+1);
    iota(ALL(tmp),0);
    CHT<int,inf> dp(tmp);
    dp.add(1,0);
    auto seq=Zalgo(s);

    set<int> ok;
    rep(i,1,n)ok.insert(i);
    ok.insert(inf);
    map<int,vector<int>> elem;
    rep(i,1,n)elem[seq[i]].push_back(i);
    rep(i,0,n){
        for(auto& x:elem[i])ok.erase(x);

        if(i){
            int j=i+1,val=dp.getmin(i+1),add=1;
            for(;;){
                int nxt=*ok.lower_bound(j);
                if(nxt==inf)break;
                val+=nxt-j;
                j=nxt+i+1;
                add++;
                dp.add_segment(1,val+add-j,j,n+1);
            }
        }
        // rep(j,0,n+1)cerr<<dp.getmin(j)<<(j==n?'\n':' ');
    }

    int ret=dp.getmin(n);
    io.write(ret);
    
    // int nai=naive(s);
    // if(nai!=ret){
    //     io.write(s,ret,nai);
    //     return 0;
    // }
    // else cerr<<s<<'\n';
    // }
    return 0;
}
0