Submission #1191114

#TimeUsernameProblemLanguageResultExecution timeMemory
1191114shadow_samiBoarding Passes (BOI22_passes)C++20
100 / 100
499 ms28148 KiB
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
typedef long long int ll;
typedef vector<ll> vi;
typedef vector<vector<ll>> vvi;
typedef pair<ll,ll> pi;
typedef map<ll,ll> mi;
typedef long double ld;
typedef vector<ld> vd;
typedef vector<vector<ld>> vvd;
typedef pair<ld,ld> pd;
#define ff first
#define ss second
#define srt(a) sort(a.begin(),a.end());
#define fip(k, n) for (ll i = k; i < n; i++)
#define fjp(k, n) for (ll j = k; j < n; j++)
#define fin(k, n) for (ll i = k; i >= n; i--)
#define fjn(k, n) for (ll j = k; j >= n; j--)
#define fp(k, n, m) for (ll k = n; k < m; k++)
#define fn(k, n, m) for (ll k = n; k >= m; k--)
#define ordered_set tree<pi, null_type,less< pi >, rb_tree_tag,tree_order_statistics_node_update>
#define totalOne(n) __builtin_popcount(n)
#define backZero(n) __builtin_ctzll(n)
#define frontZero(n) __builtin_clzll(n)
#define fx(k) for ( auto x : k )
#define test ll t;cin >> t;while (t--)
#define nli "\n"

// ==========================(debug)============================================================================================== //

#ifdef SAMI
	#define debug(x) cerr<<#x;cerr<<" ";_printn(x);cerr<<nli;
	#define debg() cerr<<nli;
#else
	#define debug(x)
	#define debg() 
#endif


void _printn(ll x){ cerr<<x<<" "; }
void _printn(int x){ cerr<<x<<" "; }
void _printn(ld x){ cerr<<x<<" "; }
void _printn(double x){ cerr<<x<<" "; }
void _printn(string x){ cerr<<x<<" "; }
void _printn(char x){ cerr<<x<<" "; }
void _printn(bool x){ cerr<<x<<" "; }
template<class T,class V>void _printn(pair<T,V> vv);
template<class T> void _printn(vector<T> vv);
template<class T> void _printn(set<T> vv);
template<class T,class V> void _printn(map<T,V> vv);
template<class T> void _printn(multiset<T> vv);
template<class T,class V>void _printn(pair<T,V> vv){ cerr<<"( ";_printn(vv.ff);cerr<<",";_printn(vv.ss);cerr<<")";}
template<class T> void _printn(vector<T> vv){ cerr<<"[ "; for(auto xx:vv){ _printn(xx);cerr<<" "; } cerr<<"]"; };
template<class T> void _printn(set<T> vv){ cerr<<"{ "; for(auto xx:vv){ _printn(xx);cerr<<" "; } cerr<<"}"; };
template<class T> void _printn(multiset<T> vv){ cerr<<"{ "; for(auto xx:vv){ _printn(xx);cerr<<" "; } cerr<<"}"; };
template<class T,class V> void _printn(map<T,V> vv){ cerr<<"{ "; for(auto xx:vv){ _printn(xx);cerr<<" "; } cerr<<"}"; };

// ==========================(debug)============================================================================================== //

ll n,m,tp,tp2,res,cnt,sum,tptp,ans;
const ll mx = 1e5+5;
const ll mod = 1e9+7;

// ==========================(MOD)=============================================================================================== //

ll mod_add(ll aa,ll bb){ return ((aa%mod)+(bb%mod))%mod; }
ll mod_minus(ll aa,ll bb){ return (((aa%mod)-(bb%mod))+10*mod)%mod; }
ll mod_mul(ll aa,ll bb){ return ((aa%mod)*(bb%mod))%mod; }
ll mod_power(ll aa,ll bb){ aa%=mod; ll empowered = 1; bb%=mod-1; while(bb > 0){ if(bb & 1) empowered = mod_mul(empowered,aa); bb = bb >> 1; aa = mod_mul(aa,aa); } return empowered; }
ll mod_divi(ll aa,ll bb){ aa=mod_mul(aa,mod_power(bb,mod-2)); return aa; }

// ==========================(MOD)=============================================================================================== //

bool f = false;
string s;
bool mark[mx];
vi lis[mx];
ld dp[1<<16];
ll to[100];
ll from[100];
ll pref[20][mx];
ll suf[20][mx];
ll c[20];

ld get(ld aa,ld bb){
	ld rss = aa * (aa-1);
	rss += bb * (bb-1);
	return (rss/4.0);
}

ld calc(ll id,ll x,ll bt){
    ld pt = 0;
    fjp(0,tp){
        if(bt & (1<<j))
            pt += pref[j][lis[x][id]];
    }
    fjp(0,tp){
        if(bt & (1<<j))
            pt += suf[j][lis[x][id+1]];
    }
    pt += get(id+1,cnt-id-1);    
    return pt;
}

int main(){
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());	
    #ifdef SAMI
        freopen("input1.txt", "r", stdin);
        freopen("output1.txt", "w", stdout);
        freopen("error1.txt", "w", stderr);
    #endif // ONLINE_JUDGE

        cin>>s;
        // fip(0,899)
        //     cout<<'A';
        n = s.size();
        set<char> st;
        fx(s)
        	st.insert(x);
        tp = st.size();
        fip(0,(1<<tp))
            dp[i] = 1e18;        
        cnt = 0;     
        fx(st){

            to[cnt] = x-'A';
            from[x-'A'] = cnt;
            cnt++;
        }
        cnt = 0;        
        fjp(0,tp){
            cnt = 0;     
            fip(0,tp)
                c[i] = 0;
            fip(0,n){
                tp2 = s[i]-'A';
                if(from[tp2]==j)
                    cnt++;
                else{                    
                    c[from[tp2]] += cnt;
                    pref[j][i] = c[from[tp2]];
                }
                // if(j==2){
                //     debug(cnt);
                //     debug(c[from[tp2]]);
                // }   
            }
        }
        cnt = 0;
        fjp(0,tp){
            cnt = 0;        
            fip(0,tp)
                c[i] = 0;
            fin(n-1,0){
                tp2 = s[i]-'A';
                if(from[tp2]==j)
                    cnt++;
                else{                    
                    c[from[tp2]] += cnt;
                    suf[j][i] = c[from[tp2]];
                }
            }
        }
        // fip(0,n)
        //     cout<<suf[2][i]<<" ";
        // cout<<nli;
        ll l,r,mid1,mid2;
        ld g1,g2;
        dp[0] = 0;       
        cnt = 0;
        fip(0,n)
        	lis[s[i]-'A'].push_back(i);        
        cnt = 0;
        fip(1,1<<tp){
        	// v = {1,4,3,6,5};    
            fjp(0,tp){
                if(i & (1<<j))
                    mark[to[j]] = 1;
                else
                    mark[to[j]] = 0;
            }    	
            fjp(0,tp){
                ld rs = 0;     
                ld sm = 0;           
                if(i & (1<<j)){                    
                    tp2 = i-(1<<j);                          
                    ll x = to[j];                    
                    mark[x] = 0;                    
                    cnt = lis[x].size();                   
                    sm = 0;
                    if(i==23){ debug(j);}
                    fp(k,0,tp){
                        if(tp2 & (1<<k)){
                            sm += suf[k][lis[x][0]];
                        }
                    }
                    rs = sm + get(0,cnt);
                    sm = 0;
                    fp(k,0,tp){
                        if(tp2 & (1<<k)){
                            sm += pref[k][lis[x][lis[x].size()-1]];
                        }
                    }                    
                    rs = min(rs,sm + get(0,cnt));
                    debug((ll)lis[x].size())
                    if(lis[x].size()> 1){
                        l = 0;
                        r = lis[x].size() - 2;
                        while(r-l>=3){
                            mid1 = l + (r-l) / 3;
                            mid2 = r - (r-l) / 3;
                            g1 = calc(mid1,x,tp2);
                            g2 = calc(mid2,x,tp2);                            
                            if(g1 > g2)
                                l = mid1;                                
                            else
                                r = mid2;                                
                        }
                        fp(tt,l,r+1) {                        
                            rs = min(rs,calc(tt,x,tp2));                    
                        }
                    }
                    mark[x] = 1;
                    // if(i==7  && dp[i] > dp[tp2]+rs){
                    //     debg();
                    //     debug(l);
                    //     debug(r);
                    //     debug(tp2);
                    //     debug(dp[tp2]+rs);
                    //     cerr<<bitset<3>(tp2)<<nli;
                    // }
                    dp[i] = min(dp[i],dp[tp2]+rs);
                }
            }    
            // debug(i)    	;
            // cerr<<bitset<3>(i)<<nli;
            // debug(dp[i]);

        }
        tp = (1ll<<tp) - 1;
        cout<<setprecision(20)<<dp[tp]<<nli;
        
    cerr << "Time elapsed: " << setprecision(6) << 1000.0 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...