Luogu P3674 小清新人渣的本愿 题解
P3674 小清新人渣的本愿
lxl大爷的题,%%%%%
以及CSP rp++!!!
前言:
其实是这题的名字吸引了我,毕竟人渣的本愿里的角色我觉得多多少少都沾点,哪来的小清新啊。《人渣的本愿》,又名《只要是【】子,睡过了也没问题是吗》。
解析:
一个 bitset
的小技巧(亦或是一种套路?)。
区间询问,不带修改,可以离线,并且是毒瘤lxl的题,考虑莫队。
在常规的莫队维护桶之外,用 bitset
来维护区间中的数用没有出现过,考虑查询时维护答案。
对于减法操作,若当前序列中存在
可移项得:
设一个 bitset
为 ,则有 s[b] = true
且 s[b + x] = true
,则相当于 中存在一个 。
对于加法操作,若当前序列中存在
我们设 ,其中 为一个常数,有:
然后我们移项可得
之后,仿照我们减法操作的处理形式:s[a] = true
,同时 s[a + (N - x)] = true
,即 存在一个 。这时为了防止加减法操作相互影响,我们再开一个 bitset
维护下 出现过没有即可。
因为 bitset
不能维护负数(没有负下标),所以 要是一个极大值,让 顶着数据范围即可。
对于乘法操作,我们直接枚举,只有 个约数,所以单次查询的复杂度是 的,由于 bitset
自带 的常数,所以总复杂度是 的,可以通过本题。
Code
#include<cmath> #include<cstdio> #include<bitset> #include<algorithm> using namespace std; const int MAXN = 1e5 + 10; int n, m, siz, lim; int num[MAXN]; int belong[MAXN], temp[MAXN], ans[MAXN]; bitset<MAXN> add, cut; struct Question{ int opt, l, r, x, id; }q[MAXN]; bool cmp(const Question &a, const Question &b){ if(belong[a.l] != belong[b.l]) return belong[a.l] < belong[b.l]; if(belong[a.l] & 1) return a.r < b.r; return a.r > b.r; } inline int read(){ int x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9'){ if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9'){ x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return x * f; } void Add(int x){ ++temp[x]; if(temp[x] == 1){ add[x] = 1; cut[lim - x] = 1; } } void Del(int x){ --temp[x]; if(temp[x] == 0){ add[x] = 0; cut[lim - x] = 0; } } void Modify(int l, int r){ for(register int i = 1; i <= m; i++){ while(l < q[i].l) Del(num[l++]); while(l > q[i].l) Add(num[--l]); while(r < q[i].r) Add(num[++r]); while(r > q[i].r) Del(num[r--]); int opt = q[i].opt, x = q[i].x; if(opt == 1) ans[q[i].id] = (add & (add << x)).any(); else if(opt == 2) ans[q[i].id] = (cut & (add << (lim - x))).any(); else{ for(register int d = 1; d * d <= x; d++){ if(x % d != 0) continue; if(add[d] && add[x / d]){ ans[q[i].id] = 1; break; } } } } } void init(){ siz = sqrt(n); for(register int i = 1; i <= siz; i++){ int st = n / siz * (i - 1) + 1; int ed = n / siz * i; for(register int j = st; j <= ed; j++) belong[j] = i; } } int main(){ n = read(), m = read(); for(register int i = 1; i <= n; i++) num[i] = read(); lim = MAXN; init(); for(register int i = 1; i <= m; i++){ q[i].opt = read(); q[i].l = read(), q[i].r = read(), q[i].x = read(); q[i].id = i; } sort(q + 1, q + 1 + m, cmp); Modify(1, 0); for(register int i = 1; i <= m; i++){ if(ans[i]) puts("hana"); else puts("bi"); } return 0; }
以下为博客签名,与博文无关。
只要你们不停下来,那前面就一定有我。所以啊,不要停下来~
本文来自博客园,作者:TSTYFST,转载请注明原文链接:https://www.cnblogs.com/TSTYFST/p/16704466.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理