搜索加贪心
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <complex>
#include <bitset>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double pi = acos(-1.0);
const int maxn = 1000111;
const int mask = 65536;
const double eps = 1e-6;
bitset<maxn * 5 + 111> vis;
int sum[maxn];
int num[maxn];
bitset<maxn + 111> ok;
int sqr[maxn];
int bit[20];
vector<int> v[mask + 2];
vector<int>::iterator it;
void init() {
int i, j;
vis[0] = vis[1] = 1;
ok[0] = 1;
for (i = 2; i * i <= 5000000; ++i)
if (!vis[i])
for (j = i * i; j <= 5000000; vis[j] = 1, j += i)
;
for (i = 1; i <= maxn; ++i) {
for (j = i; j <= maxn; j += i) {
sum[j] += i;
num[j]++;
}
}
for (i = 1; i <= 1000; ++i)
sqr[i * i] = i;
for (i = 1; i <= maxn; ++i) {
if (sqr[i])
ok[i] = sqr[sqr[i]] > 0;
else
ok[i] = (num[i] & 3) == 0;
}
bit[0] = 0;
for (i = 1; i < 20; ++i)
bit[i] = bit[i >> 1] + (i & 1);
}
const int N = 5111;
int res[maxn];
int s[6], size;
int st[25];
int cnt[25];
PII cards[N];
bool cmp(const PII& a, const PII& b) {
return bit[a.first] > bit[b.first];
}
void print(int n) {
while (n)
printf("%d", n & 1), n >>= 1;
puts("");
}
int main() {
//freopen("D:\\a.in", "r", stdin);
//freopen("D:\\ans.out","w",stdout);
ios::sync_with_stdio(false);
init();
int n, k, i, j, a, b, p, T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &k);
memset(cnt, 0, sizeof(cnt));
for (i = 0; i < n; ++i) {
scanf("%d%d", &a, &b);
p = 0;
p |= (!vis[a]);
p |= (!vis[num[a]]) << 1;
p |= (!vis[sum[a]]) << 2;
p |= (ok[a]) << 3;
res[i] = p;
cards[i] = PII(p, b);
}
for (i = 0; i < 4; ++i)
scanf("%d", s + i);
for (i = 0; i < n; ++i) {
if (i)
putchar(' ');
printf("%d", bit[res[i]]);
}
puts("");
LL ans = -(1LL << 62), tmp;
sort(cards, cards + n, cmp);
//for(i=0;i<n;++i)
// cout<<"first "<<cards[i].first<<endl;
for (j = 0; j < 16; ++j) {
tmp = 0;
p = 0;
int remain = k, t;
for (i = 0; i < n && remain > 0; ++i) {
if ((cards[i].first & j) == 0) {
p |= cards[i].first;
t = min(cards[i].second, remain);
tmp += t * bit[cards[i].first];
remain -= t;
}
}
// cout<<"tmp "<<tmp<<" "<<p<<endl;
for (i = 0; i < 4; ++i) {
if (((p >> i) & 1) == 0)
tmp += s[i];
}
if (!remain)
ans = max(ans, tmp);
//cout<<j<<" "<<p<<" "<<tmp<<" "<<remain<<endl;
}
printf("%I64d\n", ans);
}
return 0;
}