Submission #999729

#TimeUsernameProblemLanguageResultExecution timeMemory
999729pccBoarding Passes (BOI22_passes)C++17
100 / 100
456 ms169044 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define pll pair<ll,ll> #define pii pair<int,int> #define fs first #define sc second #define tlll tuple<ll,ll,ll> const ll inf = 1e18; const int mxg = 15; const int mxn = 1e5+10; ll prec[mxg][mxg][mxn]; int G,N; string s; vector<int> pos[mxg]; ll dp[1<<mxg];//ans * 4 void getprec(int a,int b){ if(a == b)return; ll sum = 0; int cnt = 0; for(int i = 0;i<=N;i++){ if(s[i] == 'A'+a)sum += cnt; else if(s[i] == 'A'+b)cnt++; prec[a][b][i] += sum; } sum = 0; cnt = 0; for(int i = N;i>=0;i--){ prec[a][b][i] += sum; if(s[i] == 'A'+a)sum += cnt; else if(s[i] == 'A'+b)cnt++; } return; } ll f(ll from,ll cut,int add){ ll re = 0; for(int i = 0;i<G;i++){ if(from&(1<<i))re += prec[add][i][cut]*4; } ll p = upper_bound(pos[add].begin(),pos[add].end(),cut)-pos[add].begin(); re += p*(p-1)+1ll*(pos[add].size()-p)*(int(pos[add].size())-p-1); return re; } void trans(int from,int to,int add){ int l = 0,r = int(pos[add].size()); for(int i = 0;i<20&&l < r;i++){ int mid = (l+r)>>1; int fl = (mid?f(from,pos[add][mid-1],add):f(from,0,add)); int fr = f(from,pos[add][mid],add); if(fl<=fr)r = mid; else l = mid+1; } //if((from^(1<<add)) == (1<<5)-1)cout<<add<<":"<<l<<' '<<r<<endl; if(l)dp[to] = min(dp[to],dp[from]+f(from,pos[add][l-1],add)); else dp[to] = min(dp[to],dp[from]+f(from,0,add)); if(r)dp[to] = min(dp[to],dp[from]+f(from,pos[add][r-1],add)); else dp[to] = min(dp[to],dp[from]+f(from,0,add)); return; } int main(){ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin>>s; N = s.size(); s = "#"+s; for(int i = 1;i<=N;i++){ pos[s[i]-'A'].push_back(i); G = max(G,int(s[i]-'A'+1)); } for(int i = 0;i<G;i++){ for(int j = 0;j<G;j++){ getprec(i,j); } } cerr<<"PREC"<<endl; fill(dp,dp+(1<<mxg),inf); dp[0] = 0; for(int i = 0;i<(1<<G);i++){ for(int j = 0;j<G;j++){ if(!(i&(1<<j)))trans(i,i^(1<<j),j); } } cerr<<dp[(1<<G)-1]<<'\n'; cout<<fixed<<setprecision(20)<<double(dp[(1<<G)-1])/4.0<<'\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...