Randomness
Author: Ryan Fu
Using randomized algorithms to solve problems.
Sometimes, we can use randomized algorithms to solve tasks quite difficult for deterministic algorithms.
Example - Ghd
Focus Problem – try your best to solve this problem before continuing!
Let the answer be . The key observation for this problem is that a randomly selected integer in has at least a chance to be divisible by .
Thus, we can repeat the following procedure times to find the optimal answer with probability :
- Let be a randomly selected value in .
- For each divisor , determine how many numbers divides into in .
- Take our answer to be the minimum of all such that numbers in are divisible by
If we take , and estimate the number of testcases in Codeforces to be , our probability of success is , which is acceptable.
Implementation
Our approach has a time complexity of , with the log factor occurring due to GCD computation, and the sqrt due to factoring.
#include <bits/stdc++.h>using namespace std;const int MAX_N = 1e6 + 5;const int S = 15;mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());long long a[MAX_N], dv[MAX_N], cnt[MAX_N];int main() {
Example - Count on a Tree II Striking Back
Focus Problem – try your best to solve this problem before continuing!
Trying to solve this problem directly - explicitly finding values for and - is quite difficult. Supporting online queries of range count distinct along with updates is quite difficult to achieve on an array in reasonable complexity, and the fact that this problem occurs on a tree, with relative large bound for makes it clear that solving for the value of is not intended.
Instead, we can attempt to use the property given in the statement that either or . This inspires the following thought - if we map each color to a random number, the path minimum along the path with more distinct colors will probably be a smaller value.
We attempt to formalize this approach, and push the probability to an acceptable bound. Notably, the probability of failure is too high when we do the aforementioned random process once. To remedy this, we proceed as follows:
- First we fix to be the number of "simulations" that we run.
- Next, for each possible color , we define as an independent random value within , for each .
- Then, we construct trees , of the same structure as the initial tree, but with marked on a node .
- For each query comparing , we output if
and otherwise.
This approach should "combine" the probabilities in a way that makes the more likely event (the path with more distinct values achieving a smaller value) exponentially more likely. For some intuition on this, if we flip a coin weighted with probability to be heads once, there is a probability it comes up tails more than heads. However, if we flip it times, the probability it comes up more tails more than heads becomes
Calculating the exact probability that our approach works is more difficult than the coin toss example, but follows the same principle of failure becoming exponentially more unlikely across several trials. We can use some assumptions (notably the central limit theorem) to calculate a rough approximation of the probability of success. Here is a graph of the probability of passing the problem given a certain value of . Note that the probability of success remains is largely the same across different counts of distinct colors along the path.
The graph was generated for the probability of answering queries correctly in a row. This assumption is reasonable because the test data consists of only 1 large test case.
The python code used to generate the estimates is shown below:
import mathfrom scipy.stats import normdef clt_probability(k, S):"""Computes the probability that the sum of S minima from 2k random drawsis less than the sum of S minima from k random draws, as approximated by the CLT.The CLT approximation is given by:
Implementation
By supporting path queries with HLD, we can solve this problem in .
#include "bits/stdc++.h"using namespace std;using us = unsigned short;const int MAX_N = 5e5 + 1;const int S = 150;const us INF = 65535;us va[MAX_N][S];
Problems
Some of the listed problems do not require random algorithms as a solution, but can be made significantly easier through using random algorithms.
Status | Source | Problem Name | Difficulty | Tags | ||
---|---|---|---|---|---|---|
MHC | Easy | Show TagsRandom | ||||
CF | Normal | Show TagsRandom | ||||
CF | Normal | Show TagsRandom | ||||
CF | Normal | Show TagsRandom |
Module Progress:
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!