Namomo Test Round 1的B Hat[概率题:详解]

题目链接


Namomo Test Round 1的B Hat[概率题:详解]_第1张图片


解题思路:1.我们设第i个位置里面有兔子的概率是 p i p_i pi初始的时候除了第一个位置是概率是1其他位置都是0
2.对于看见的过程我们直接 s w a p ( p i , p j ) swap(p_i,p_j) swap(pi,pj)
3.对于看不见的情况对于一个i位置我们它有兔子概率是 p i p_i pi,这个位置不被选中的概率是 n − 2 n n-2\over n nn2[因为一个 C ( n , 2 ) 种 选 法 , 不 选 它 有 C ( n − 1 , 2 ) 种 选 法 相 除 化 简 就 是 n − 2 n C(n,2)种选法,不选它有C(n-1,2)种选法相除化简就是{n-2\over n} C(n,2)C(n1,2)nn2]那么概率就是 n − 2 n ∗ p i {n-2\over n}*p_i nn2pi
4.假如说这个帽子 i i i被选中了那么概率是 1 − n − 2 n = 2 n , 那 么 被 先 选 中 要 乘 以 这 个 帽 子 里 面 没 有 兔 子 的 概 率 以 及 于 这 个 帽 子 交 换 另 外 的 帽 子 里 面 有 兔 子 的 概 率 1-{n-2\over n}={2\over n},那么被先选中要乘以这个帽子里面没有兔子的概率以及于这个帽子交换另外的帽子里面有兔子的概率 1nn2=n2,
5.这样才能加进 p i p_i pi因为 p i p_i pi的意义就是这个帽子有兔子的概率
6.那么被选中整体的式子就是: ( 1 − p i ) ∗ 2 n ∗ 1 n − 1 (1-p_i)*{2\over n}*{1\over n-1} (1pi)n2n11
7.合并一下就是 p i = n − 2 n ∗ p i + ( 1 − p i ) ∗ 2 n ∗ 1 n − 1 p_i={n-2\over n}*p_i+(1-p_i)*{2\over n}*{1\over n-1} pi=nn2pi+(1pi)n2n11


前面我们提到初始的时候除了 p 1 = 1 , 其 他 都 是 0 , 那 么 在 除 了 p 1 之 外 或 者 是 其 他 位 置 你 可 能 看 见 1 被 交 换 了 , 其 他 位 置 的 概 率 都 是 一 样 的 p_1=1,其他都是0,那么在除了p_1之外或者是其他位置你可能看见1被交换了,其他位置的概率都是一样的 p1=1,0p11


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define mid ((l + r) >> 1) 
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define _for(i,a,b) for( int i = (a); i < (b); ++i)
#define _rep(i,a,b) for( int i = (a); i <= (b); ++i)
#define rep_(i,a,b) for( int i = (a); i >= (b); -- i)
#define for_(i,a,b) for( int i = (a); i > (b); -- i)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define hash Hash
#define next Next
#define count Count
#define pb push_back
#define f first
#define s second
using namespace std;
const int N = 1e5+10, mod = 998244353;
const double eps = 1e-10;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
template<typename T> void read(T &x)
{
    x = 0;char ch = getchar();ll f = 1;
    while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
    while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args) 
{
    read(first);
    read(args...);
}
ll qmi(ll a, ll b)
{
    ll res = 1;
    while(b)
    {
        if(b & 1) res = (res * a) % mod;
        b >>= 1;
        a = (a * a) % mod;
    }
    return res % mod;
}
struct node 
{
   ll id, l, r;    
}e[N];
int T;
int n, m ,k;
int main()
{
    read(T);
    while(T --)
    {
         ms(e,0);
         read(n,m,k);
         _for(i,0,k) 
         {
             int l, r, w;
             cin >> w >> l >> r;
             e[i] = (node){w,l,r};
         }
         ll niv1 = qmi(n,mod - 2), niv2 = qmi(n-1,mod - 2);
         ll q = 1, p = 0, poi = 0, pos = 1;
         _for(i,1,m+1)
         {
             if(e[poi].id == i && poi < k)
             {
                 if(e[poi].l == pos) pos = e[poi].r;
                 else if(e[poi].r == pos) pos = e[poi].l;
                 poi ++;
             }
             else 
             {
                 q = (2 * niv1 * niv2 % mod) * ((1 - q + mod) % mod) + ((n - 2) * niv1 % mod * q) % mod;
                 q %= mod;
                 p = (2 * niv1 * niv2 % mod) * ((1 - p + mod) % mod) + ((n - 2) * niv1 % mod * p) % mod;
                 p %= mod;
             }
         }
         _for(i,1,n+1)
           if(i == pos) cout << q << " ";
           else cout << p << " ";
           cout << endl;
    }
    return 0;
}

你可能感兴趣的:(概率与期望)