洛谷 P3674 小清新人渣的本愿
- a - b = x 可以转换成 a = b + x.用bitset记录区间数的种类,存在a - b = x 等价于 bitset & bitset<<x 是否有1
- a + b = x 可以记b = N - B,也就是判断 a - B = x - N是否存在,另外记录一个bitset就能转化到两数之差
- a * b = x 直接枚举因子即可
codes
const int maxn = 1e5 + 7;
int n, t, m, k;
int a[maxn], ans[maxn];
struct query {
int id, op, x, l, r;
} q[maxn];
bool cmp(query a, query b) {
if (a.l / k == b.l / k)
return a.r < b.r;
return a.l / k < b.l / k;
}
bitset<maxn> now, eth;
int cnt[maxn], nct[maxn];
void add(int x) {
cnt[x]++, nct[maxn - x]++;
now.set(x);
eth.set(maxn - x);
}
void del(int x) {
cnt[x]--, nct[maxn - x]--;
if (cnt[x] == 0)
now.reset(x);
if (nct[maxn - x] == 0)
eth.reset(maxn - x);
}
void solve() {
cin >> n >> m;
k = (int) sqrt(maxn);
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= m; i++) {
cin >> q[i].op >> q[i].l >> q[i].r >> q[i].x;
q[i].id = i;
}
sort(q + 1, q + 1 + m, cmp);
int l = 1, r = 0;
for (int i = 1; i <= m; i++) {
int pl = q[i].l, pr = q[i].r;
while (l > pl) add(a[--l]);
while (r < pr) add(a[++r]);
while (l < pl) del(a[l++]);
while (r > pr) del(a[r--]);
if (q[i].op == 1) {
ans[q[i].id] = (int) (now & (now << q[i].x)).any();
} else if (q[i].op == 2) {
ans[q[i].id] = (int) (now & (eth >> (maxn - q[i].x))).any();
} else {
for (int c = 1; c * c <= q[i].x; c++) {
if (q[i].x % c) continue;
if (now[c] && now[q[i].x / c])
ans[q[i].id]++;
}
}
}
for (int i = 1; i <= m; i++)
if (ans[i]) cout << "hana" << endl;
else cout << "bi" << endl;
}
我看见 你