<style> .reveal .slides { text-align: left; font-size:28px; } </style> ## random --- * 要怎麼random(產生亂數) * random可以用在哪裡 * 想辦法靠賽 ---- ## 產生亂數 ---- 在數學意義上並沒有真正的亂數,因此都只能用時間種子或者是怪怪的公式去假裝亂數 所以我們今天使用的是時間種子 ```cpp chrono::steady_clock::now().time_since_epoch().count() ``` 那記得使用這個要引入標頭檔 ```cpp #include<chrono> ``` 這是一個單位以 ms 來計算的時間亂數 ---- 那我們分析一下這是什麼,大家就不用自己去找了 ```cpp chrono::steady_clock::now().time_since_epoch().count() ``` 首先 $steady\_clock$ 是一個單調的時鐘 然後 $now()$ 就是指現在的時間 接著 $time\_since\_epoch()$ 是指 現在獲取的 $now$ 到時間元年的間隔 最後 $count()$ 當然就是指有幾個間隔 *時間元年 1970/01/01 ---- 再來是產生器,我們會使用到的是 mt19937 什麼是mt19937呢,背後支持的數學演算法是梅森旋轉算法,可以使得在一個範圍內有隨機分布。 那要怎麼產生呢? ```cpp mt19937 變數名稱(亂數種子); ``` 所以我們的定義就會變成 ```cpp mt19937 mt(chrono::steady_clock::now().time_since_epoch().count()); ``` ---- 那我們就可以開始利用mt了 那因為mt是我們的產生器,我們還需要給他一個分布的範圍 ```cpp uniform_int_distribution<> dis(0, 1e9); ``` 那他的預設值就是int 如果今天要用小數點的話就分別是以下 ```cpp uniform_int_distribution<int> 分布變數名稱(最小值, 最大值); uniform_real_distribution<double> 分布變數名稱(最小值, 最大值); ``` ---- 所以最後就會這樣寫出東西 ```cpp #include<iostream> #include<random> #include<chrono> using namespace std; void solve(){ mt19937 mt(chrono::steady_clock::now().time_since_epoch().count()); uniform_int_distribution<> dis(0, 1e9); cout<<dis(mt)<<endl; } int main(){ solve(); return 0; } ``` --- ## random 可以用在哪裡? ---- * shuffle() ---- 就 shuffle 阿 ```cpp shuffle(arr,arr+n,mt); ``` 跟sort的用法一樣,代表直接把你的arr全部打亂 就這樣。 --- ## 想辦法讓你靠賽是對的 * MOD * 眾數 ---- ## MOD 如題 MOD 2 的話,那就隨機兩次(X ---- ## 眾數 *絕對眾數 數字出現次數超過長度的一半 ---- 給你長度為N的 arr,Q筆詢問 每次詢問給出區間 L , R ,詢問裡面的區間絕對眾數是誰? ---- 你會發現,在區間裡面戳一個數字,它會是區間絕對眾數的機率會有$\frac 1 2$ 所以我們只要戳30次 這樣連戳30次都不是眾數的機率是 ${\frac 1 2}^{30}$ 就這樣。 那要怎麼確認一個數字是不是區間絕對眾數呢? ---- 把每個數字的index記錄下來 然後使用二分搜去算它在此區間有幾個數字,就可以知道它是不是區間絕對眾數 因此複雜度是 $O(30 Q log N)$ ---- ## 作業例題 給你一個長度為 $n$ 的 arr ,求出一個 MOD 讓這個 arr 有絕對眾數 要取模誒 那他怎麼可能可以隨機? 還真可以。 因為在 MOD 完之後他會是絕對眾數,因此你任選一個數字,它取模完會是眾數的機率是 $\frac 1 2$ 所以隨機挑選兩個數字,兩個都是眾數的機率是 $\frac 1 4$ ,然後枚舉 $|x-y|$ 的質因數 當成模數去計算即可。 ---- ## 分析 一次取到兩個都是眾數的機會是 $\frac 1 4$ 也就是說不是的機率是 $\frac 3 4$ 那我只需要 ${\frac 3 4}^T$ 就可以保證會是對的。 --- [練習題單 ](https://vjudge.net/contest/598374#problem/D) 這種東西只能找機率XD
{"title":"random","slideOptions":"{\"transition\":\"fade;\"}","description":"要怎麼random(產生亂數)","contributors":"[{\"id\":\"e4a3af8b-860c-46a0-96f1-558667fdcf41\",\"add\":2291,\"del\":31},{\"id\":\"19f09ccf-6b99-452f-971f-955cfc1657f3\",\"add\":11,\"del\":4},{\"id\":\"08326fa4-ca9b-4ca9-873e-239ebe76662c\",\"add\":371,\"del\":365}]"}
    840 views
   owned this note