QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#328142 | #8005. Crossing the Border | Dualqwq | WA | 4869ms | 70940kb | C++20 | 2.9kb | 2024-02-15 17:34:27 | 2024-02-15 17:34:27 |
Judging History
answer
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 23,Sz = 1 << 22,Sm = 1 << 12,P = 998244353;
int n,V;
struct node { int w,c;} p[N];
int sum[Sz],lb[Sz];
struct Data {
int v,s;
Data(){v = 1.5e9;s = 0;}
Data(const int _v,const int _s):v(_v),s(_s){}
Data operator + (const int &rhs) const { return Data(v + rhs,s);}
Data operator * (const Data &rhs) const {
if(v < rhs.v) return *this;
if(v > rhs.v) return rhs;
return Data(v,(s + rhs.s) % P);
}
Data& operator *= (const Data &rhs) {
if(v > rhs.v) *this = rhs;
else if(v == rhs.v) { s += rhs.s;if(s >= P) s -= P;}
return *this;
}
};
Data dp[Sz];
vector<int> sp1[Sm],sp2[Sm];
Data pmn[Sm];
int main() {
cin >> n >> V;
for(int i = 0;i < n;i++) cin >> p[i].w >> p[i].c;
// int st = clock();
sort(p,p + n,[&](const node &a,const node &b) { return a.c > b.c;});
int mid = n / 2,all = (1 << n);
for(int i = 0;i < n;i++) sum[1 << i] = p[i].w;
for(int i = 0;i < all;i++) sum[i] = sum[i & (i - 1)] + sum[i & (-i)];
for(int i = 0;i < all;i++) lb[i] = __lg(i & (-i));
// for(int i = 0;i < all;i++) if(sum[i] <= V) dp[i] = Data(p[lb[i]].c,1);
for(int i = 0;i < (1 << mid);i++) {
for(int j = i;j;j = (j - 1) & i)
if(j != i) sp1[i].push_back(j);
sp1[i].push_back(0);
sort(sp1[i].begin(),sp1[i].end(),[&](const int &x,const int &y) { return sum[x] > sum[y];});
}
for(int i = 0;i < (1 << n - mid);i++) {
for(int j = i;j < (1 << n - mid);j = (j + 1) | i)
sp2[i].push_back(j << mid);
sort(sp2[i].begin(),sp2[i].end(),[&](const int &x,const int &y) { return sum[x] > sum[y];});
}
dp[0] = Data(0,1);
for(int i = 1;i < all;i++)
if(!(i & ((1 << mid) - 1)))
for(int j = i;j;j = (j - 1) & i)
if(((j >> lb[i]) & 1) && sum[j] <= V)
dp[i] *= (dp[i - j] + p[lb[i]].c);
for(int i = 0;i < all;i++) { // i 的左半边为等待更新的集合,i 的右半边为更新超集的集合
int L = i & ((1 << mid) - 1),R = i >> mid;
if(!L) continue;
int len = sp2[R].size();
for(int j = 0;j < len;j++) pmn[j].v = 1.5e9,pmn[j].s = 0; // 可行的是一段后缀
for(int p1 = 0,p2 = 0;p1 < sp1[L].size();++p1) {
while(p2 < len && sum[sp2[R][p2]] - sum[R << mid] + sum[L] - sum[sp1[L][p1]] > V) ++p2;
if(p2 < len)
pmn[p2] *= dp[(R << mid) | sp1[L][p1]];
}
for(int i = 1;i < len;i++) pmn[i] *= pmn[i - 1];
for(int i = 0;i < len;i++)
dp[sp2[R][i] | L] *= (pmn[i] + p[lb[L]].c);
}
printf("%d\n%d\n",dp[all - 1].v,dp[all - 1].s);
// int ed = clock();
// cerr << (ed - st) * 1.0 / CLOCKS_PER_SEC << endl;
return 0;
}
/*
22 10000000
956231 904623
1692946 1796774
1081323 1170319
3218792 2542661
3183376 3037270
1869132 1442561
35436 35018
1564635 1939950
1847344 2006043
755870 899310
1671882 2057413
1369264 1338951
3132483 3504034
2056224 1825640
1840949 1562071
1514040 1405352
2300821 2421801
2466540 3004920
1514040 1405352
1369264 1338951
35436 35018
1369264 1338951
*/
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 36668kb
input:
5 5 3 5 1 4 2 3 2 2 2 1
output:
9 4
result:
ok 2 number(s): "9 4"
Test #2:
score: 0
Accepted
time: 122ms
memory: 38936kb
input:
18 10000000 956231 904623 1692946 1796774 1081323 1170319 3218792 2542661 3183376 3037270 1869132 1442561 35436 35018 1564635 1939950 1847344 2006043 755870 899310 1671882 2057413 1369264 1338951 3132483 3504034 2056224 1825640 1840949 1562071 1514040 1405352 2300821 2421801 2466540 3004920
output:
9391997 70
result:
ok 2 number(s): "9391997 70"
Test #3:
score: 0
Accepted
time: 849ms
memory: 45520kb
input:
20 10000000 1289384 1416015 1692778 1966748 1747794 1708650 2885387 2925290 2516650 2410838 2202363 2092667 368691 407497 1897764 1902790 180541 224758 1089173 1075924 2005212 1743637 702568 566295 465783 369143 2722863 2902398 174068 150211 513930 519657 1634023 1313239 1133070 1040937 961394 11066...
output:
6331196 89
result:
ok 2 number(s): "6331196 89"
Test #4:
score: 0
Accepted
time: 2017ms
memory: 54132kb
input:
21 10000000 1432782 1230128 1693282 1456826 605524 521515 2742745 3427204 2231114 2129928 2345527 2397808 511783 521160 2041234 2313965 2323807 2603481 1232121 1410811 719508 850004 416942 495559 2180169 2579591 1580089 1786914 2317568 2292171 1514260 1143717 1348703 1495001 562052 525544 2818854 23...
output:
9336572 5
result:
ok 2 number(s): "9336572 5"
Test #5:
score: 0
Accepted
time: 4869ms
memory: 70940kb
input:
22 10000000 1562592 1176882 1693226 1513484 2293770 2757728 2612851 3010518 1971354 2392268 2475363 2035487 641627 684375 2171036 2181775 1544541 1633457 1361981 1060447 2277948 2792254 157192 141039 1011327 1139897 541119 577682 1538276 1451191 2423314 2061841 1088919 1154927 42526 43789 1779858 16...
output:
8019829 516
result:
ok 2 number(s): "8019829 516"
Test #6:
score: -100
Wrong Answer
time: 3320ms
memory: 70916kb
input:
22 50000000 9900000 50000000 9800000 50000000 9700000 50000000 9600000 50000000 9500000 50000000 9400000 50000000 9300000 50000000 9200000 50000000 9100000 50000000 9190000 50000000 9180000 50000000 9170000 50000000 9160000 50000000 9150000 50000000 9140000 50000000 9130000 50000000 9120000 50000000...
output:
250000000 121860904
result:
wrong answer 2nd numbers differ - expected: '659827482', found: '121860904'