SP5652 PATULJCI - Snow White and the N dwarfs 题解

题目传送门

思路

众所周知,当拿到一道题但是不会做的时候,可以考虑随机化。

首先,我们用 vector 记录每种颜色在那些位置出现过,每次在区间里随机一个位置,看这个位置对应的颜色在此区间内是否出现大于长度除以二。这样进行大概 20 20 20 次,一交,竟然对了!

后来想了想,确实能对。这种算法会错当且仅当存在答案但没随机到。如果存在答案,那么随机一次没随机到的概率就是 1 2 \frac 1 2 21,随机 k k k 次都没随机到的概率是 1 2 k \frac 1 {2^k} 2k1。随机 20 20 20 次出错的概率大约是 1 1 0 6 \frac 1 {10^6} 1061,而询问只有 1 0 5 10^5 105 组。只要不是运气极差,就能轻松 AC。

什么,你说你瞧不起没有正确性保证的算法?那你以后就不要用哈希了!

代码

#include <bits/stdc++.h>
using namespace std;

template<typename T> inline void read(T &x)
{
	x = 0;
	T f = 1;char ch = getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')
		{
			f = -1,ch = getchar();
			break;
		}
		ch = getchar();
	}
	while(ch>='0'&&ch<='9')
		x = (x<<3)+(x<<1)+ch-48,ch = getchar();
	x*=f;
}
template<typename T> inline T read()
{
	T x;read(x);return x;
}
template<typename T> void write(T x)
{
    if(x<0) x = -x,putchar('-');
    if(x>9) write(x/10);
    putchar(x%10+48);
}
template<typename T> inline void writen(T x)
{
    write(x);
    putchar(10);
}
const int N = 3e5+5;
int n,c,q,a[N];
vector<int> v[N];
inline void solve()
{
	int l,r;
	read(l),read(r);
	for(int _ = 1;_<=20;_++)//随机 20 次
	{
		int p = l+rand()%(r-l+1);
		int res = upper_bound(v[a[p]].begin(),v[a[p]].end(),r)-lower_bound(v[a[p]].begin(),v[a[p]].end(),l);//确定个数
		if(res>(r-l+1)/2) return putchar('y'),putchar('e'),putchar('s'),putchar(32),writen(a[p]);
	}
	puts("no");
}
signed main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	srand(time(0));
	read(n),read(c);
	for(int i = 1;i<=n;i++)
		read(a[i]),v[a[i]].push_back(i);
	for(int i = 1;i<=c;i++)
		v[i].push_back(n+1);
	read(q);
	while(q--) solve();
	return 0;
}

后记

双倍经验,虽然是个蓝题。

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值