Advertisement
Fshl0

Untitled

Feb 22nd, 2022
633
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.80 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define BITS __builtin_popcountll
  6. typedef long long ll;
  7.  
  8.  
  9.  
  10.  
  11. const ll MAX = (ll)1e5 + 5;
  12.  
  13.  
  14. ll segTree[MAX << 2], m;
  15.  
  16.  
  17. void Build(ll node, ll nodeL, ll nodeR, const string& s) {
  18.  
  19.     if (nodeL == nodeR) {
  20.         segTree[node] |= (1 << (ll)(s[nodeL] - 'a'));
  21.         return;
  22.     }
  23.  
  24.     ll mid = (nodeL + nodeR) >> 1;
  25.     ll leftNode = node + 1;
  26.     ll rightNode = node + ((mid - nodeL + 1) << 1);
  27.     Build(leftNode, nodeL, mid, s);
  28.     Build(rightNode, mid + 1, nodeR, s);
  29.     segTree[node] = (segTree[leftNode] | segTree[rightNode]);
  30.  
  31. }
  32.  
  33.  
  34. pair<ll, ll> Query(ll node, ll nodeL, ll nodeR, ll l, ll r,
  35.                       ll mask, ll k) {
  36.  
  37.     if (l > r) {
  38.         return {0, 0};
  39.     }
  40.  
  41.     ll mid = (nodeL + nodeR) >> 1;
  42.     ll leftNode = node + 1;
  43.     ll rightNode = node + ((mid - nodeL + 1) << 1);
  44.  
  45.     if ((nodeL == l) && (nodeR == r)) {
  46.         if (BITS(mask | segTree[node]) >= k) {
  47.             if (nodeL == nodeR) {
  48.                 return {(mask | segTree[node]), nodeR + 1};
  49.             }
  50.             else {
  51.  
  52.                 if (BITS(mask | segTree[leftNode]) >= k) {
  53.                     return Query(leftNode, nodeL, mid, l, min(mid, r),
  54.                                   mask, k);
  55.                 }
  56.                 else {
  57.                     return Query(rightNode, mid + 1, nodeR, max(mid + 1, l), r,
  58.                                  (mask | segTree[leftNode]), k);
  59.                 }
  60.  
  61.             }
  62.         }
  63.         else {
  64.             return {(mask | segTree[node]), 0};
  65.         }
  66.     }
  67.  
  68.     pair<ll, ll> leftTry = Query(leftNode, nodeL, mid, l, min(mid, r),
  69.                                     mask, k);
  70.  
  71.     if (BITS(leftTry.first) == k) {
  72.         return leftTry;
  73.     }
  74.  
  75.     return Query(rightNode, mid + 1, nodeR, max(mid + 1, l), r,
  76.                  (mask | leftTry.first), k);
  77.  
  78. }
  79.  
  80.  
  81. long long Solve(ll i, const vector<ll>& c, vector<long long>& dp) {
  82.  
  83.     if (i == (ll)dp.size()) {
  84.         return 0;
  85.     }
  86.  
  87.     long long& res = dp[i];
  88.     if (res != -1) {
  89.         return res;
  90.     }
  91.  
  92.     res = LONG_LONG_MAX;
  93.     for (ll j = 0; j < m; j++) {
  94.  
  95.         ll newIndex = Query(0, 0, (ll)dp.size() - 1, i, (ll)dp.size() - 1,
  96.                               0, j + 1).second;
  97.  
  98.         res = min(res, Solve(newIndex, c, dp) + c[j]);
  99.         if (newIndex == (ll)dp.size()) {
  100.             break;
  101.         }
  102.  
  103.     }
  104.  
  105.     return res;
  106.  
  107. }
  108.  
  109.  
  110. int main() {
  111.  
  112.     ios_base :: sync_with_stdio(0);
  113.     cin.tie(0);
  114.     cout.tie(0);
  115.  
  116.     ll n;
  117.     cin >> n;
  118.     string s;
  119.     cin >> s;
  120.    
  121.     cin >> m;
  122.     vector<ll> c(26);
  123.     for (ll i = 0; i < m; i++) {
  124.         cin >> c[i];
  125.     }
  126.  
  127.     Build(0, 0, n - 1, s);
  128.  
  129.     vector<long long> dp(n, -1);
  130.     cout << Solve(0, c, dp);
  131.  
  132.     return 0;
  133.  
  134. }
  135.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement