害怕,帖被删了、、、
vp 时调了 90min 一直 WA,现在又 WA#11,有没有做过的大佬救救菜鸡啊!
具体思想就是二进制分组然后背包一下。
#include <bits/stdc++.h>
#define i64 long long
#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()
#define rep(i, a, b) for (int i = (a); i < (b); ++i)
#define per(i, a, b) for (int i = (b) - 1; i >= (a); --i)
using namespace std;
const int N = 2e5 + 1, Nk = 20;
const i64 B = 1e5;
int nq, n, a[N], fa[Nk][N], lg[N];
bitset<N> f;
vector<int> split(int x) {
vector<int> s;
for (int p = 1; p <= x; p <<= 1) {
s.push_back(p), x -= p;
}
x ? s.push_back(x) : void();
return s;
}
int main() {
// freopen("D.in", "r", stdin);
// freopen("D.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> nq >> n, n += 1;
rep(i, 1, n) {
a[i] = -1, lg[i] = __builtin_ctz(i);
}
f[0] = true, a[0] = 0;
rep(i, 0, nq) {
i64 x;
int o, y;
cin >> o >> x >> y;
vector<int> s = split(y);
if (o == 1) {
x = (x + B - 1) / B;
for (const int &u : s) {
f |= f << x * u;
}
} else if (o == 2) {
per(j, 0, n) {
fa[0][j] = min<i64>((x * j + B - 1) / B, n);
rep(k, 0, Nk - 1) {
if (fa[k][j] >= n) {
break;
}
fa[k + 1][j] = fa[k][fa[k][j]];
}
}
for (const int &u : s) {
per(j, 0, n) {
int k = j, v = u;
while (k < n and v) {
k = fa[lg[v & -v]][k];
v ^= v & -v;
}
k < n and f[j] ? f[k] = true : 0;
}
}
}
rep(j, 0, n) {
if (a[j] == -1 and f[j]) {
a[j] = i + 1;
}
}
}
rep(i, 1, n) {
cout << a[i] << ' ';
}
cout << '\n';
return 0;
}