QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#463477 | #8713. 不要玩弄字符串 | PorNPtree | WA | 1530ms | 189220kb | C++17 | 2.9kb | 2024-07-04 21:29:36 | 2024-07-04 21:29:38 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int N = 18, L = 180;
int n, sum[1 << N], hv[L], ch[2][L], tot;
void insert(string S, int id) {
int now = 0;
for (int c : S) {
c -= '0';
if (!ch[c][now]) ch[c][now] = ++tot;
now = ch[c][now];
}
hv[now] |= (1 << id);
}
int fail[L];
void build() {
queue<int> Q;
for (int i = 0; i < 2; ++i) {
if (ch[i][0]) Q.push(ch[i][0]);
}
while (!Q.empty()) {
int x = Q.front();
Q.pop();
for (int i = 0; i < 2; ++i) {
if (ch[i][x]) fail[ch[i][x]] = ch[i][fail[x]], Q.push(ch[i][x]);
else ch[i][x] = ch[i][fail[x]];
}
}
for (int i = 0; i <= tot; ++i) hv[i] |= hv[fail[i]];
}
int f[1 << N][L], du[L];
vector<int> rG[L];
void dp() {
memset(f, -0x3f, sizeof(f));
for (int i = 0; i <= tot; ++i) f[(1 << n) - 1][i] = 0;
for (int i = (1 << n) - 2; ~i; --i) {
for (int j = 0; j <= tot; ++j) du[j] = 0, rG[j].clear();
for (int j = 0; j <= tot; ++j) for (int k = 0; k < 2; ++k) {
if ((hv[ch[k][j]] | i) != i) {
f[i][j] = max(f[i][j], -f[hv[ch[k][j]] | i][ch[k][j]] + sum[hv[ch[k][j]] & ~i]);
} else {
rG[ch[k][j]].push_back(j);
++du[j];
}
}
priority_queue< pair<int, int> > pq;
for (int j = 0; j <= tot; ++j) pq.push(make_pair(f[i][j], j));
int cnt = tot + 1;
queue<int> Q;
for (int j = 0; j <= tot; ++j) if (!du[j]) {
Q.push(j);
}
while (cnt) {
while (!Q.empty()) {
int x = Q.front(); Q.pop(), --cnt;
for (auto v : rG[x]) {
f[i][v] = max(f[i][v], -f[i][x]);
pq.push(make_pair(f[i][v], v));
if (!--du[v]) Q.push(v);
}
}
if (cnt) {
while (1) {
int y = pq.top().second;
pq.pop();
if (du[y] <= 0) continue;
if (f[i][y] <= 0) {
for (int j = 0; j <= tot; ++j) if (du[j] > 0) f[i][j] = 0;
cnt = 0;
break;
}
du[y] = 0;
Q.push(y);
break;
}
}
}
}
}
signed main() {
scanf("%d", &n);
for (int i = 0, V; i < n; ++i) {
string S; cin >> S;
insert(S, i);
scanf("%d", &V);
for (int j = 0; j < 1 << n; ++j) if ((j >> i) & 1) sum[j] += V;
}
build();
dp();
int q; scanf("%d", &q);
while (q--) {
string S; cin >> S;
int now = 0, sta = 0;
for (int c : S) now = ch[c - '0'][now], sta |= hv[now];
printf("%d\n", f[sta][now]);
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 3ms
memory: 188428kb
input:
3 11 1 0 2 000 3 2 0 1
output:
-1 3
result:
ok 2 number(s): "-1 3"
Test #2:
score: 0
Accepted
time: 794ms
memory: 189156kb
input:
18 111101 -31301 1101101 53902 101001 77190 1000110 -26277 01010 84183 0111001 -89769 100100 31681 00101 -33612 00101000 -25238 00111 -93542 0001101 45298 01100010 63521 11001001 84789 001011 89827 11010101 -12647 01011100 18677 010100 174 10011111 -73155 524286 0 1 00 10 01 11 000 100 010 110 001 1...
output:
0 0 0 0 0 0 0 0 0 0 0 77190 0 0 0 0 0 0 0 -77190 0 0 0 0 84183 77190 0 0 0 0 0 0 0 0 0 77190 0 0 0 31681 0 -77190 0 0 0 0 0 26277 0 53108 89827 84183 77190 77190 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77190 77190 0 0 0 0 0 0 31681 -53108 0 0 -77190 -77190 0 0 0 0 0 0 0 0 0 0 26277 26277 0 0 53108 53108...
result:
ok 524286 numbers
Test #3:
score: -100
Wrong Answer
time: 1530ms
memory: 189220kb
input:
18 01 3 000 13 100 9 011 1 0101 6 0011 16 0100 12 0111 10 00100 15 1110 2 011111 18 100100 6 1010001 8 10101100 3 1001000 9 00100001 12 001100 8 10111111 2 524286 0 1 00 10 01 11 000 100 010 110 001 101 011 111 0000 1000 0100 1100 0010 1010 0110 1110 0001 1001 0101 1101 0011 1011 0111 1111 00000 100...
output:
10 0 10 10 -7 0 3 13 13 10 9 -7 8 0 3 0 13 13 20 13 8 12 0 9 -7 -7 8 8 2 0 3 0 0 0 16 13 13 13 33 34 8 13 9 8 0 12 0 9 9 9 -7 -7 -8 -9 17 8 8 8 2 2 16 0 3 0 0 0 -3 0 0 0 3 -1 13 13 8 13 13 13 33 24 22 34 8 8 14 15 17 8 8 8 0 0 0 12 0 9 9 9 9 9 8 7 -16 0 -7 -7 -8 -8 0 -9 17 8 8 8 8 7 8 10 -7 2 2 2 16...
result:
wrong answer 40th numbers differ - expected: '8', found: '34'