#include using namespace std; #ifdef DEB #define D if(1) #else #define D if(0) #endif #define fo(a,b) for(int a=0;a<(b);++a) using ll = long long; const int KMAX = 27; const int NMAX = 212345; int n, k; ll money[KMAX]; ll opt_money; char in[NMAX]; struct Node { char inside = 0; ll val ; ll val_nogar; int size = 0; }; Node dp[NMAX]; #define NOPE (-(1ll<<40)) void prline(int i) { printf("%d [%lld %lld] %d\n", dp[i].inside, dp[i].val, dp[i].val_nogar, dp[i].size); } int main(int argc, char ** argv) { scanf("%d %s",&n,in); scanf("%d",&k); fo(i,k) { char c; ll val; scanf(" %c %lld", &c, &val); money[c-'A'+1]=val; opt_money = max(opt_money, val); } fo(i,n) in[i] = in[i]=='?'?0:in[i]-'A'+1; int p; for(p=2;n%p;p++); fo(i,n) { dp[i].inside = in[i]; dp[i].size = 1; if(in[i]) { dp[i].val = money[in[i]]; dp[i].val_nogar = money[in[i]]; } else { dp[i].val = opt_money; dp[i].val_nogar = opt_money; } } int start = n; int old_start = 0; int jump = n/p; int count = p; for(;jump; jump/=p, count*=p) { D printf("-----------------\n"); fo(i, jump) { Node & out = dp[start+i]; fo(j,p) { Node & act = dp[old_start+i+j*jump]; out.size += act.size; out.val_nogar += act.val_nogar; if(!out.inside) out.inside = act.inside; if(act.inside && out.inside && out.inside!=act.inside) out.inside = 100; } out.size+=count; if(!out.inside) out.val = out.size * opt_money; else if(out.inside == 100) out.val = 0; else out.val = out.size * money[out.inside]; out.val_nogar = max(out.val, out.val_nogar); D prline(start+i); } old_start = start; start += jump; } printf("%lld\n",dp[old_start].val_nogar); return 0; }