This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
// Willkommen! hier ist der Ort, an dem du sterben wirst :)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define all(x) x.begin(), x.end()
#define pb push_back
#define fi first
#define se second
const int maxn5 = 1e5 + 10;
const ll inf = 1e18;
const int lg = 30;
const int al = 15; /// REMEMBER YOU'VE CHANGED THISSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
vector <int> av[al + 2];
ll lef[al + 1][maxn5], rig[al + 1][maxn5];
ll pslef[al + 1][maxn5], psrig[al + 1][maxn5];
ll dp[1 << al];
inline bool check(int id, int lim, int mask){
ll val = 2 * lim - int(av[id].size()) + 1;
for(int i = 0; i < al; i++) if((mask >> i)&1)
val += 2 * (lef[i][av[id][lim]] - rig[i][av[id][lim]]);
return val <= 0;
}
int main(){
ios_base::sync_with_stdio(false); cin.tie(0);
string s; cin >> s;
int n = s.size();
for(int i = 0; i < n; i++)
av[s[i] - 'A'].pb(i);
lef[s[0] - 'A'][0] = 1;
for(int i = 1; i < n; i++){
for(int j = 0; j < al; j++){
lef[j][i] = lef[j][i - 1] + (s[i] - 'A' == j);
}
}
rig[s[n - 1] - 'A'][n - 1] = 1;
for(int i = n - 2; i >= 0; i--){
for(int j = 0; j < al; j++){
rig[j][i] = rig[j][i + 1] + (s[i] - 'A' == j);
}
}
for(int i = 0; i < al; i++) if(av[i].size()){
for(int j = 0; j < al; j++)
pslef[j][av[i][0]] = lef[j][av[i][0]];
for(int j = 1; j < av[i].size(); j++) for(int k = 0; k < al; k++)
pslef[k][av[i][j]] = pslef[k][av[i][j - 1]] + lef[k][av[i][j]];
reverse(all(av[i]));
for(int j = 0; j < al; j++)
psrig[j][av[i][0]] = rig[j][av[i][0]];
for(int j = 1; j < av[i].size(); j++) for(int k = 0; k < al; k++)
psrig[k][av[i][j]] = psrig[k][av[i][j - 1]] + rig[k][av[i][j]];
reverse(all(av[i]));
}
for(int mask = 1; mask < (1 << al); mask++){
dp[mask] = inf;
for(int i = 0; i < al; i++) if((mask >> i)&1){
if(av[i].empty()){
dp[mask] = dp[mask ^ (1 << i)];
break;
}
ll lo = -1, hi = av[i].size();
while(hi - lo > 1){
int mid = (lo + hi) >> 1;
if(check(i, mid, mask ^ (1 << i)))
lo = mid;
else
hi = mid;
}
ll len = av[i].size();
ll val = hi * (hi - 1) + (len - hi) * (len - hi - 1);
//cout << val << endl;
if(lo > -1){
for(int j = 0; j < al; j++) if(j != i && ((mask >> j)&1))
val += 4 * pslef[j][av[i][lo]];
}
//cout << val << endl;
if(hi < av[i].size()){
for(int j = 0; j < al; j++) if(j != i && ((mask >> j)&1))
val += 4 * psrig[j][av[i][hi]];
}
dp[mask] = min(dp[mask], dp[mask ^ (1 << i)] + val);
//cout << "ok " << mask << ' ' << i << ' ' << lo << ' ' << val << ' ' << dp[mask] << endl;
}
}
ll ans = dp[(1 << al) - 1];
if(ans % 4 == 0)
cout << ans / 4 << endl;
else if(ans % 2 == 0)
cout << ans / 4 << ".5" << endl;
else
cout << ans / 4 << ".25" << endl;
}
/*
HEHEHEHIHILOL
ABABABACACDED
*/
Compilation message (stderr)
passes.cpp: In function 'int main()':
passes.cpp:58:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
58 | for(int j = 1; j < av[i].size(); j++) for(int k = 0; k < al; k++)
| ~~^~~~~~~~~~~~~~
passes.cpp:63:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
63 | for(int j = 1; j < av[i].size(); j++) for(int k = 0; k < al; k++)
| ~~^~~~~~~~~~~~~~
passes.cpp:91:19: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
91 | if(hi < av[i].size()){
| ~~~^~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |