Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Merge branch 'master' of https://github.com/l1nkus/cpptemplates
- Loading branch information
Showing
1 changed file
with
89 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#include <bits/stdc++.h> | ||
#include <ext/pb_ds/assoc_container.hpp> | ||
#include <ext/pb_ds/tree_policy.hpp> | ||
#define pb push_back | ||
#define mp make_pair | ||
#define all(a) begin(a),end(a) | ||
#define FOR(x,val,to) for(int x=(val);x<int((to));++x) | ||
#define FORE(x,val,to) for(auto x=(val);x<=(to);++x) | ||
#define FORR(x,arr) for(auto &x: arr) | ||
#define FORS(x,plus,arr) for(auto x = begin(arr)+(plus); x != end(arr); ++x) | ||
#define FORREV(x,plus,arr) for(auto x = (arr).rbegin()+(plus); x !=(arr).rend(); ++x) | ||
#define REE(s_) {cout<<s_<<'\n';exit(0);} | ||
#define GET(arr) for(auto &i: (arr)) sc(i) | ||
#define whatis(x) cerr << #x << " is " << (x) << endl; | ||
#define e1 first | ||
#define e2 second | ||
#define INF 0x7f7f7f7f | ||
typedef std::pair<int,int> pi; | ||
typedef std::vector<int> vi; | ||
typedef std::vector<std::string> vs; | ||
typedef int64_t ll; | ||
typedef uint64_t ull; | ||
#define umap unordered_map | ||
#define uset unordered_set | ||
using namespace std; | ||
using namespace __gnu_pbds; | ||
|
||
#ifdef ONLINE_JUDGE | ||
#define whatis(x) ; | ||
#endif | ||
#ifdef _WIN32 | ||
#define getchar_unlocked() _getchar_nolock() | ||
#define _CRT_DISABLE_PERFCRIT_LOCKS | ||
#endif | ||
template<class L, class R> ostream& operator<<(ostream &os, map<L, R> P) { for(auto const &vv: P)os<<"("<<vv.first<<","<<vv.second<<")"; return os; } | ||
template<class T> ostream& operator<<(ostream &os, set<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; } | ||
template<class T> ostream& operator<<(ostream &os, vector<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; } | ||
template<class L, class R> ostream& operator<<(ostream &os, pair<L, R> P) { os<<"("<<P.first<<","<<P.second<<")"; return os; } | ||
inline int fstoi(const string &str){auto it=str.begin();bool neg=0;int num=0;if(*it=='-')neg=1;else num=*it-'0';++it;while(it<str.end()) num=num*10+(*it++-'0');if(neg)num*=-1;return num;} | ||
inline void getch(char &x){while(x = getchar_unlocked(), x < 33){;}} | ||
inline void getstr(string &str){str.clear(); char cur;while(cur=getchar_unlocked(),cur<33){;}while(cur>32){str+=cur;cur=getchar_unlocked();}} | ||
template<typename T> inline bool sc(T &num){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){if(c == EOF) return false;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; return true;}template<typename T, typename ...Args> inline void sc(T &num, Args &...args){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; sc(args...); } | ||
template<typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; //s.find_by_order(), s.order_of_key() <- works like lower_bound | ||
template<typename T> using ordered_map = tree<T, int, less<T>, rb_tree_tag, tree_order_statistics_node_update>; | ||
#define N 1000001 | ||
|
||
|
||
// Primitive root modulo n exists if and only if: | ||
// n is 1, 2, 4, or | ||
// n is power of an odd prime number (n=p^k), or | ||
// n is twice power of an odd prime number (n=2*p^k). | ||
// https://cp-algorithms.com/algebra/primitive-root.html | ||
// The following code assumes that the modulo p is a prime number. To make it works for any value of p, we must add calculation of ϕ(p). | ||
int powmod (int a, int b, int p) { | ||
int res = 1; | ||
while (b) | ||
if (b & 1) | ||
res = int (res * 1ll * a % p), --b; | ||
else | ||
a = int (a * 1ll * a % p), b >>= 1; | ||
return res; | ||
} | ||
|
||
int generator (int p) { | ||
vector<int> fact; | ||
int phi = p-1, n = phi; | ||
for (int i=2; i*i<=n; ++i) | ||
if (n % i == 0) { | ||
fact.push_back (i); | ||
while (n % i == 0) | ||
n /= i; | ||
} | ||
if (n > 1) | ||
fact.push_back (n); | ||
|
||
for (int res=2; res<=p; ++res) { | ||
bool ok = true; | ||
for (size_t i=0; i<fact.size() && ok; ++i) | ||
ok &= powmod (res, phi / fact[i], p) != 1; | ||
if (ok) return res; | ||
} | ||
return -1; | ||
} | ||
|
||
int main(){ | ||
ios_base::sync_with_stdio(0);cin.tie(0); | ||
whatis(generator(200003)) | ||
} | ||
|