CF1746F Kazaee

prologue

数组范围一定要看好了开,不然容易我一样,调试调了一页多。

还有就是不要傻乎乎地只跑一次和哈希,因为和哈希(从下面地佬的题解中才知道)它其实算作是一种 trick(类比SA(Stimulate_anneal)。

analysis

这个题目的第二个询问时询问一个区间里面出现过的正整数的次数是否为 k 的倍数。这个题可以说是这个题目的 pro plus 版本。这样子的话么,我们就可以往这个方面考虑。

我们再继续分析这个题目。

我们和上面所示的例题一样,将统计出现次数,哈希一下。

然后,我们记 G(l,r) 为一个区间里面的数字哈希和,如果满足题目中的性质,那么我们会有:

kG(l,r)

证明:取其中的一个数 ai 为例,出现了 k 次则相加和一定为 k
ai倍数。对于满足条件的 G(l,r) 其中每一个数都满足条件,由此得证。

最后我们就转化成了给每一个数字的哈希值求和,然后看这个值能否整除 k

还有就是对于这个里面的时候进行离散化要考虑好常数问题,然后选择合适的方法进行离散化。

然后我们分析一下正确性,对于一个区间限制最坏的情况是存在一对数 (x,y),满足 kcntx+cnty,kcntx,kcnty 那么这个时候我们判断错误当且仅当 (x,y) 全被选,或者 (x,y) 全不选。我们随机判错的概率是 12,所以当我们进行了 B 次判断,我们判错的概率就是 12B,这个时候取到 B=30 即可。

code time

#include <bits/stdc++.h> using namespace std; #define ll long long #define rl register ll #define lowbit(x) (x & -x) mt19937 rnd; // 一个很好用的随机化,与rand相比这个会更快一点,听别的题解们说不用这个会被卡/fad template <class T> // 快读板子 inline void read(T &res) { char ch; bool f = 0 ; while((ch = getchar()) < '0' || ch > '9') f |= ch == '-'; res = ch ^ 48; while((ch = getchar()) <= '9' && ch >= '0') res = (res << 1) + (res << 3) + (ch ^ 48); res = f ? ~res + 1 : res; } const ll N = 3e5 + 10; ll n, a[N], m, lst[N]; ll tr[N], ls[N << 2], tot, rd[N << 2]; // 想好数组大小 bool ans[N]; struct node { ll op, x, y, z; }q[N << 1]; inline ll Rand(ll l, ll r) { uniform_int_distribution<ll>distribution(l, r); return distribution(rnd); } inline void add(ll x, ll c) { for(; x <= n; x += lowbit(x)) tr[x] += c; } inline ll sum(ll x) { ll res = 0; for(; x; x -= lowbit(x)) res += tr[x]; return res; } int main() { // freopen("1.in", "r", stdin), freopen("1.out", "w", stdout); read(n), read(m); for(rl i=1; i <= n; ++ i) { read(a[i]); ls[ ++ tot] = a[i]; } for(rl i=1; i <= m; ++ i) { read(q[i].op), read(q[i].x), read(q[i].y); if(q[i].op == 1) ls[ ++ tot] = q[i].y; else read(q[i].z); } sort(ls + 1, ls + 1 + tot); tot = unique(ls + 1, ls + 1 + tot) - ls - 1; for(rl i=1; i <= n; ++ i) a[i] = lower_bound(ls + 1, ls + 1 + tot, a[i]) - ls; for(rl i=1; i <= m; ++ i) if(q[i].op == 1) q[i].y = lower_bound(ls + 1, ls + 1 + tot, q[i].y) - ls; memset(ans, 1, sizeof ans); for(rl i=0; i < 30; ++ i) { memset(tr, 0, sizeof tr); for(rl i=1; i <= tot; ++ i) rd[i] = Rand(1, 1e9); for(rl i=1; i <= n; ++ i) lst[i] = a[i]; for(rl i=1; i <= n; ++ i) add(i, rd[a[i]]); for(rl i=1; i <= m; ++ i) { if(q[i].op == 1) { add(q[i].x, -rd[lst[q[i].x]]); lst[q[i].x] = q[i].y; add(q[i].x, rd[lst[q[i].x]]); } else ans[i] &= ((sum(q[i].y) - sum(q[i].x - 1)) % q[i].z == 0); } } for(rl i=1; i <= m; ++ i) if(q[i].op == 2) (ans[i] == 1) ? puts("YES") : puts("NO"); return 0; }

__EOF__

本文作者carp
本文链接https://www.cnblogs.com/carp-oier/p/17751477.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   carp_oier  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示