Templates
Templates
................................................................. }
Return factors in O(log(n)) + O(nlog(log(n))) preprocessing sort(all(ret));
.................................................................. return ret;
#define MAXN 10000001 }
int spf[MAXN]; ......................................................................
void sieve() Binary Exponentiation
{ ----------------------------------------------------------------------
spf[1] = 1; long long binpow(long long a, long long b) {
for (int i = 2; i < MAXN; i++) a %= mod;
spf[i] = i; long long res = 1;
for (int i = 4; i < MAXN; i += 2) while (b > 0) {
spf[i] = 2; if (b & 1)
res = res * a % mod;
for (int i = 3; i * i < MAXN; i++) { a = a * a % mod;
if (spf[i] == i) { b >>= 1;
for (int j = i * i; j < MAXN; j += i) }
if (spf[j] == j) return res%mod;
spf[j] = i; }
}
} long long inv(long long x) {
} return binpow(x, mod - 2);
vector<int> getFactorization(int x) }
{ ......................................................................
vector<int> ret; Number of Bits less than the given number
while (x != 1) { ----------------------------------------------------------------------
ret.push_back(spf[x]); long long counts(long long num,long long cur,long long always,bool
x = x / spf[x]; tight){
} if(cur<0)
return ret; return 1;
} if(tight){
.................................................................... if(num&(1ll<<cur)){
Returns Prime factors in O(sqrt(n)) if(always!=cur)
-------------------------------------------------------------------- return counts(num,cur-1,always,0)+counts(num,cur-
vector<long long> factor(long long n) { 1,always,1);
vector<long long> ret; else
for (long long i = 2; i * i <= n; i++) { return counts(num,cur-1,always,1);
while (n % i == 0) { }
ret.push_back(i); else{
n /= i; if(always==cur)
} return 0;
} else
if (n > 1) { ret.push_back(n); } return counts(num,cur-1,always,1);
return ret; }
} }
...................................................................... else{
Return all factors in O(sqrt(n)) if(cur>=always){
---------------------------------------------------------------------- return (1ll<<cur);
vector<long long> factor(long long n){ }
vector<long long> ret; else{
for(int i=1;i<=sqrt(n);i++){ return (1ll<<(cur+1));
if(n%i==0){ }
if(i*i==n) }
ret.push_back(i); }
else
ret.push_back(i),ret.push_back(n/i); long long total(long long num){
long long ans=0; int len = edge.second;
for(long long i=59;i>=0;i--){
ans+=counts(num,59,i,1); if (d[v] + len < d[to]) {
} q.erase({d[to], to});
return ans; d[to] = d[v] + len;
} p[to] = v;
...................................................................... q.insert({d[to], to});
Tarjan Algorithm to find bridges }
---------------------------------------------------------------------- }
void dfs(int i, int par, vector<int> &level, vector<int> &dp, }
vector<vector<int>> &adj, set<pair<int, int>> &bridges) { }
//initialize level to -1 ......................................................................
//initialise dp to 0 DSU
----------------------------------------------------------------------
dp[i] = 0; struct DSU {
for (auto x : adj[i]) { vector<long long> e;
if (level[x] == -1) { DSU(long long N) {
level[x] = level[i] + 1; e = vector<long long>(N, -1);
dfs(x, i, level, dp, adj, bridges); }
dp[i] += dp[x]; long long get(long long x) {
} return e[x] < 0 ? x : e[x] = get(e[x]);
else if (level[x] > level[i]) { }
dp[i]--; bool same_set(long long a, long long b) {
} return get(a) == get(b);
else if (level[x] < level[i]) { }
dp[i]++; long long size(long long x) {
} return -e[get(x)];
} }
dp[i]--; bool unite(long long x, long long y) {
x = get(x), y = get(y);
if (level[i] > 1 && dp[i] == 0) { if (x == y) return false;
bridges.insert({i, par}); if (e[x] > e[y]) swap(x, y);
} e[x] += e[y];
e[y] = x;
return ; return true;
} }
...................................................................... };
Dijkstra Algorithm ......................................................................
---------------------------------------------------------------------- KMP
const int INF = 1000000000; ----------------------------------------------------------------------
vector<vector<pair<int, int>>> adj; vector<int> pi(const string &s) {
int n = (int)s.size();
void dijkstra(int s, vector<int> & d, vector<int> & p) { vector<int> pi_s(n);
int n = adj.size(); for (int i = 1, j = 0; i < n; i++) {
d.assign(n, INF); while (j > 0 && s[j] != s[i]) { j = pi_s[j - 1]; }
p.assign(n, -1); if (s[i] == s[j]) { j++; }
pi_s[i] = j;
d[s] = 0; }
set<pair<int, int>> q; return pi_s;
q.insert({0, s}); }
while (!q.empty()) { Compute no of occurence of a prefix in entire string
int v = q.begin()->second; vector<int> ans(n + 1,0);
q.erase(q.begin()); for (int i = 0; i < n; i++)
ans[pis[i]]++;
for (auto edge : adj[v]) { for (int i = n-1; i > 0; i--)
int to = edge.first; ans[pis[i-1]] += ans[i];
for (int i = 0; i <= n; i++) long>>& space) {
ans[i]++; sort(space.begin(), space.end());
...................................................................... vector<pair<long long,long long>> merged;
Manchester Algorithm for (auto x : space) {
---------------------------------------------------------------------- if (merged.empty() || merged.back().second < x.first) {
class manchaster{ merged.push_back(x);
public: }
string T; else {
vector<int> P; merged.back().second = max(merged.back().second, x.second);
public: }
manchaster(const string &s):P(2*s.size()+1){ }
for(int i=0;i<s.size();i++){ return merged;
T.push_back('#'); }
T.push_back(s[i]); ......................................................................
} NCR mods
T+="#"; ----------------------------------------------------------------------
int C = 0, R = -1, rad; const long long MAXN = 2e6;
for (int i = 0; i < T.length(); ++i) { const long long MOD = 1e9 + 7;
if (i <= R) {
rad = min(P[2*C-i], R-i); long long fac[MAXN + 1];
} else { long long inv[MAXN + 1];
rad = 0;
} long long exp(long long x, long long n, long long m) {
while (i+rad < T.length() && i-rad >= 0 && T[i-rad] x %= m;
== T[i+rad]) { long long res = 1;
rad++; while (n > 0) {
} if (n % 2 == 1) { res = res * x % m; }
P[i] = rad; x = x * x % m;
if (i + rad - 1 > R) { n /= 2;
C = i; }
R = i + rad - 1; return res;
} }
}
for(int i=0;i<T.size();i++){ void factorial() {
P[i]=(P[i]+(2*P[i]-1)/2); fac[0] = 1;
P[i]-=(P[i]+1)/2; for (long long i = 1; i <= MAXN; i++) { fac[i] = fac[i - 1] * i
} % MOD; }
} }
function<int(int, int, int, int)> diameter = [&](int u, int p, for (int p = 1; p <= log2dist; p++) {
int d, int i) { for (int n = 0; n < par.size(); n++) {
dist[i][u] = d; int halfway = pow2ends[n][p - 1];
if (halfway == -1) { n1 = pow2ends[n1][i];
pow2ends[n][p] = -1; n2 = pow2ends[n2][i];
} else { }
pow2ends[n][p] = pow2ends[halfway][p - 1]; }
} return n1 == 0 ? 0 : pow2ends[n1][0];
} }
}
/** @return the distance between n1 and n2. */
vector<vector<int>> children(par.size()); int distance(int n1, int n2) {
for (int n = 1; n < par.size(); n++) { return depth[n1] + depth[n2] - 2 * depth[LCA(n1, n2)];
children[par[n]].push_back(n); }
} };
......................................................................
depth = vector<int>(par.size()); Trie (string)
----------------------------------------------------------------------
vector<int> frontier{0}; struct Node{
Node *link[26];
while (!frontier.empty()) { bool stop=false;
int curr = frontier.back(); int sum=0,count[26],ends=0;
frontier.pop_back(); Node(){
for (int n : children[curr]) { for(int i=0;i<26;i++){
depth[n] = depth[curr] + 1; link[i] = NULL;
frontier.push_back(n); count[i] = 0;
} }
} }
} };
class Trie{
/** @return the kth parent of node n (or -1 if it doesn't exist). */
int kth_parent(int n, int k) { Node *root;
if (k > par.size()) {
return -1; public:
}
int at = n; Trie(){
for (int pow = 0; pow <= log2dist; pow++) { root = new Node();
if ((k & (1 << pow)) != 0) { }
at = pow2ends[at][pow];
if (at == -1) { void insert(string word){
break; Node *node = root;
} for(auto x:word){
} if(node->link[x-'a']==NULL){
} node->link[x-'a']=new Node();
return at; }
} node->sum++;
node->count[x-'a']++;
/** @return the lowest common ancestor of n1 and n2. */ node = node->link[x-'a'];
int LCA(int n1, int n2) { }
if (depth[n1] < depth[n2]) { node->stop=true;
return LCA(n2, n1); node->ends++;
} }
n1 = kth_parent(n1, depth[n1] - depth[n2]);
if (n1 == n2) { int countWordsEqualTo(string word){
return n1; Node *node = root;
} for(auto x:word){
for (int i = log2dist; i >= 0; i--) { if(node->link[x-'a']==NULL){
if (pow2ends[n1][i] != pow2ends[n2][i]) { return 0;
} nxt[Sz][0] = nxt[Sz][1] = 0;
node = node->link[x-'a']; cnt[Sz] = 0;
} }
if(node->stop){ Sz = 1;
return node->ends; }
}
return 0; //use add(num,-1) to remove a element
} void add(int x,int f=1) {
int cur = 0;
int countWordsStartingWith(string word){ for(int i = LOG-1; i>= 0 ; i --) {
Node *node = root; bool y = (x >> i) & 1;
int counts=0; if(!nxt[cur][y]) {
for(auto x:word){ nxt[cur][y] = Sz ++;
if(node->link[x-'a']==NULL){ }
return 0; cnt[cur] += f;
} cur = nxt[cur][y];
counts=node->count[x-'a']; }
node = node->link[x-'a']; cnt[cur] += f;
} }
return counts;
} int get(int x) {
int cur = 0;
void erase(string word){ int ans =0;
Node *node = root; for(int i = LOG-1; i >= 0 ; i --) {
for(auto x:word){ bool y = ((x >> i)&1) ^ 1 ^ ((xo >> i)&1);
node->count[x-'a']--; if(nxt[cur][y] && cnt[nxt[cur][y]]) {
node->sum--; ans |= (1 << i);
Node *next = node->link[x-'a']; } else {
if(node->sum == 0 && node!=root){ y ^= 1;
delete node; }
} cur = nxt[cur][y];
node = next; }
} return ans;
node->ends--; }
} } tr[2];
}; ......................................................................
...................................................................... Z-Algorithm
Trie (Numbers) ----------------------------------------------------------------------
---------------------------------------------------------------------- vector<int> z(string s) {
const int N =2e5 + 23; int n = s.size();
const int LOG = 30; vector<int> z(n);
int x = 0, y = 0;
struct Trie { for (int i = 1; i < n; i++) {
int nxt[N*LOG][2]; z[i] = max(0,min(z[i-x],y-i+1));
int cnt[N*LOG]; while (i+z[i] < n && s[z[i]] == s[i+z[i]]) {
int xo = 0; x = i; y = i+z[i]; z[i]++;
int Sz = 1; }
}
Trie() { return z;
for(int i = 0 ; i < N*LOG; i ++) nxt[i][0] = nxt[i][1] = 0; }
}
void clear() {
xo = 0;
Sz += 23;
while(Sz--) {