P3792 由乃与大母神原型和偶像崇拜

随机赋权哈希,算是板子题?

主要是想记录随机赋权 hash 这个 trick

显然,我们可以通过找到 [l,r] 中的最小值 min,从而确定,这连续的一段权值是 [min,min+rl]

我们考虑如何去判断。

显然有一个简单的想法,就是对于 [1,2.5×107] 中的每一个数,随机赋一个哈希权值 vali,然后维护一个 sumi 表示 sumi=j=1ivalj

然后我们考虑维护每一个区间的 vali,i[l,r]

由于存在修改,考虑线段树维护这一过程,包括上面的区间最小值。

显然,我们最后只需要判断,summin+rlsummin1 是否与 vali,i[l,r] 相等即可。

由于是赋权,就会导致重复的概率极小,即使存在,你也可以通过选一个次数 ksumi=j=1ivaljk 来减少错误的概率。

反正就是乱搞就能过。

#include <bits/stdc++.h>
using namespace std;
#define maxn 500005
#define maxe (int)(2.5e7)
int n, m;
int a[maxn], val[maxe + 5];
long long sum[maxe + 5];
struct segmentree
{
	int l, r;
	long long data;
	int minn; 
}tree[maxn << 2];
void update(int p)
{
	tree[p].data = tree[p << 1].data + tree[p << 1 | 1].data;
	tree[p].minn = min(tree[p << 1].minn, tree[p << 1 | 1].minn);
}
void build(int p, int l, int r)
{
	tree[p].l = l, tree[p].r = r;
	if(l == r) return tree[p].data = val[a[l]], tree[p].minn = a[l], void(0);
	int mid = (l + r) >> 1;
	build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r);
	update(p);
}
void change(int p, int x, int y)
{
	if(tree[p].l > x || tree[p].r < x) return;
	if(tree[p].l == tree[p].r) return tree[p].data = val[y], tree[p].minn = y, void(0);
	change(p << 1, x, y), change(p << 1 | 1, x, y);
	update(p);
}
pair<long long, int> query(int p, int l, int r)
{
	if(tree[p].l > r || tree[p].r < l) return make_pair(0, INT_MAX);
	if(tree[p].l >= l && tree[p].r <= r) return make_pair(tree[p].data, tree[p].minn);
	pair<long long, int> now1 = query(p << 1, l, r), now2 = query(p << 1 | 1, l, r);
	return make_pair(now1.first + now2.first, min(now1.second, now2.second));
}
int main()
{
	srand(time(NULL));
	for (int i = 1; i <= maxe; ++i) val[i] = rand() % (long long)(1e11), sum[i] = sum[i - 1] + val[i];
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
	build(1, 1, n);
	while(m--)
	{
		int op, x, y;
		scanf("%d %d %d", &op, &x, &y);
		if(op == 1) change(1, x, y);
		else
		{
			pair<long long, int> ans = query(1, x, y);
			if(ans.second + (y - x) <= maxe && sum[ans.second + y - x] - sum[ans.second - 1] == ans.first) puts("damushen");
			else puts("yuanxing");
		}
	}
	return 0;
}
posted @   Saltyfish6  阅读(71)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
Document
点击右上角即可分享
微信分享提示