Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Random from Gassa */
- /* Updated by Burunduk1 and Burunduk3 */
- /** please notice all changed in this log **
- * 2009-08-15 - rndLong() was added
- * 2010-11-29 - asserts are added, comments are modified [Burunduk1]
- * 2010-11-29 - rndLong is fixed, R(ll, ll) is added [Burunduk1]
- * 2011-06-12 - bug in rndLong if fixed [Burunduk1]
- * 2013-02-15 - bug in Time() under MSVC -- do not use "low", this word is reserved
- ****/
- #ifndef __random_h__
- #define __random_h__
- #include <cmath>
- #include <cstdio>
- #include <cstdlib>
- #include <cassert>
- #include <algorithm>
- /***
- * Declarations
- ***/
- typedef unsigned uint;
- typedef long long ll;
- typedef unsigned long long ull;
- typedef long double dbl;
- #define rndvalue rndInt
- int nextrand(); // random in [0..MBIG)
- void initrand( int seed ); // initialize random
- dbl rndDouble(); // random in [0..1)
- int rndInt( int k ); // random in [0..k)
- ll rndLong( ll k ); // random in [0..k) version for "long long"
- int R( int A, int B ); // random in [A..B]
- ll R( ll A, ll B ); // random in [A..B]
- ll Time(); // returns number of tics since processor was turned on
- template <typename Type>
- void randomShuffle( Type start, Type finish ); // shuffles an array like std::random_shuffle, but using our random
- /***
- * Definitions
- ***/
- const int MBIG = (int)1e9, MSEED = 161803398;
- const double FAC = 1.0L / MBIG;
- int inext, inextp;
- int ra [56];
- int nextrand() // Random in [0..MBIG)
- {
- int j;
- if (++inext == 56)
- inext = 1;
- if (++inextp == 56)
- inextp = 1;
- j = ra[inext] - ra[inextp];
- if (j < 0)
- j += MBIG;
- ra[inext] = j;
- return j;
- }
- void initrand(int seed)
- {
- int i, j, k, l;
- seed = seed * seed + seed * 239017 + 13;
- l = MSEED - seed;
- l %= MBIG;
- if (l < 0)
- l += MBIG;
- ra[55] = l;
- k = 1;
- for (i = 1, j = 0; i <= 54; i++)
- {
- j += 21;
- if (j > 55)
- j -= 55;
- ra[j] = k;
- k = l - k;
- if (k < 0)
- k += MBIG;
- l = ra[j];
- }
- for (k = 1; k <= 4; k++)
- for (i = 1, j = 31; i <= 55; i++, j >= 55 ? j = 1 : j++)
- {
- ra[i] -= ra[j];
- if (ra[i] < 0)
- ra[i] += MBIG;
- }
- inext = 0;
- inextp = 31;
- }
- dbl rndDouble() // Random in [0..1)
- {
- return nextrand () * FAC;
- }
- int rndInt(int k) // Random in [0..k)
- {
- assert(1 <= k);
- return (int)(rndDouble () * k);
- }
- ll rndLong( ll k ) // Random in [0..x)
- {
- assert(1 <= k);
- return (ll)((rndDouble() * FAC + rndDouble()) * k);
- }
- int R( int A, int B )
- {
- assert(A <= B && (uint)B - A < (1LL << 31) - 1);
- return A + rndInt(B - A + 1);
- }
- ll R( ll A, ll B )
- {
- assert(A <= B && (ull)B - A < (1ULL << 63) - 1);
- return A + rndLong(B - A + 1);
- }
- ll Time()
- {
- #ifdef __GNUC__
- ll res;
- asm volatile ("rdtsc" : "=A" (res));
- return res;
- #else
- int loww, hi;
- __asm
- {
- rdtsc
- mov loww, eax
- mov hi, edx
- }
- return ((ll)hi << 32) | loww;
- #endif
- }
- template <typename Type>
- void randomShuffle( Type start, Type finish )
- {
- for (int i = 0; start + i != finish; i++)
- {
- int j = R(0, i);
- std::swap(*(start + i), *(start + j));
- }
- }
- #endif // __random_h__
Advertisement
Add Comment
Please, Sign In to add comment