Problem - 7386
题目大意:给出一整数n,有一个隐藏的在1~n范围内的数x,每次随机询问一个y,会得知x<y,x>y,或x=y,当可能的x唯一确定时停止询问,问期望的询问次数是多少
1<=n<=1e9
思路:用以下程序模拟这个操作后可以发现
import random
n=15
x=2
t=0
tot=0
print('n:',n)
print('x:',x)
while 1:
t+=1
if(t==100000):
break
cnt=0
l=[]
while 1:
q=random.randint(1,n)
if q not in l:
l.append(q)
cnt+=1
if x in l:
break
if x==1:
if x+1 in l:
break
if x==n:
if x-1 in l:
break
if x!=1 and x!=n:
if x-1 in l and x+1 in l:
break
tot+=cnt
print(tot/100000)
当x=1或n时,期望为n/2,当x属于2~n-1时,期望为2n/3,那么总的期望就是,因为模数998244353在n的范围内,所以要用扩展欧几里得求逆元,或者将式子进一步化简得到(2n-1)/3,1的情况因为n-2<0,所以要特判
#include<bits/stdc++.h>
//#include<__msvc_all_public_headers.hpp>
using namespace std;
typedef long long ll;
ll n;
const int N = 1e6 + 5;
const ll MOD = 998244353;
void init()
{
}
ll qpow(ll a, ll b)
{
a %= MOD;
ll ret = 1;
while (b)
{
if (b & 1)
{
ret = ret * a % MOD;
}
a = a * a % MOD;
b >>= 1;
}
return ret;
}
ll exgcd(ll a, ll b, ll& x, ll& y) //扩展欧几里得算法
{
if (b == 0)
{
x = 1, y = 0;
return a;
}
ll t = exgcd(b, a % b, y, x);
y = y - a / b * x;
return t;
}
ll Inv(ll a, ll mod) //求a在mod下的逆元,不存在逆元返回-1
{
ll x, y;
ll d = exgcd(a, mod, x, y);
return d == 1 ? (x % mod + mod) % mod : -1; //x可能是负数,转化成正数
}
void solve()
{
ll k;
cin >> n;
init();
ll ans;
if (n == 1)
ans = 0;
else
{
ll temp1 = 2 * n - 1;
ll x = qpow(3, MOD - 2);
ans = temp1 * x%MOD;
}
cout << ans << endl;
}
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
{
solve();
}
return 0;
}