Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define BITS __builtin_popcountll
- typedef long long ll;
- const ll MAX = (ll)1e5 + 5;
- ll segTree[MAX << 2], m;
- void Build(ll node, ll nodeL, ll nodeR, const string& s) {
- if (nodeL == nodeR) {
- segTree[node] |= (1 << (ll)(s[nodeL] - 'a'));
- return;
- }
- ll mid = (nodeL + nodeR) >> 1;
- ll leftNode = node + 1;
- ll rightNode = node + ((mid - nodeL + 1) << 1);
- Build(leftNode, nodeL, mid, s);
- Build(rightNode, mid + 1, nodeR, s);
- segTree[node] = (segTree[leftNode] | segTree[rightNode]);
- }
- pair<ll, ll> Query(ll node, ll nodeL, ll nodeR, ll l, ll r,
- ll mask, ll k) {
- if (l > r) {
- return {0, 0};
- }
- ll mid = (nodeL + nodeR) >> 1;
- ll leftNode = node + 1;
- ll rightNode = node + ((mid - nodeL + 1) << 1);
- if ((nodeL == l) && (nodeR == r)) {
- if (BITS(mask | segTree[node]) >= k) {
- if (nodeL == nodeR) {
- return {(mask | segTree[node]), nodeR + 1};
- }
- else {
- if (BITS(mask | segTree[leftNode]) >= k) {
- return Query(leftNode, nodeL, mid, l, min(mid, r),
- mask, k);
- }
- else {
- return Query(rightNode, mid + 1, nodeR, max(mid + 1, l), r,
- (mask | segTree[leftNode]), k);
- }
- }
- }
- else {
- return {(mask | segTree[node]), 0};
- }
- }
- pair<ll, ll> leftTry = Query(leftNode, nodeL, mid, l, min(mid, r),
- mask, k);
- if (BITS(leftTry.first) == k) {
- return leftTry;
- }
- return Query(rightNode, mid + 1, nodeR, max(mid + 1, l), r,
- (mask | leftTry.first), k);
- }
- long long Solve(ll i, const vector<ll>& c, vector<long long>& dp) {
- if (i == (ll)dp.size()) {
- return 0;
- }
- long long& res = dp[i];
- if (res != -1) {
- return res;
- }
- res = LONG_LONG_MAX;
- for (ll j = 0; j < m; j++) {
- ll newIndex = Query(0, 0, (ll)dp.size() - 1, i, (ll)dp.size() - 1,
- 0, j + 1).second;
- res = min(res, Solve(newIndex, c, dp) + c[j]);
- if (newIndex == (ll)dp.size()) {
- break;
- }
- }
- return res;
- }
- int main() {
- ios_base :: sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- ll n;
- cin >> n;
- string s;
- cin >> s;
- cin >> m;
- vector<ll> c(26);
- for (ll i = 0; i < m; i++) {
- cin >> c[i];
- }
- Build(0, 0, n - 1, s);
- vector<long long> dp(n, -1);
- cout << Solve(0, c, dp);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement