高精度运算
高精度加法:
int main() { scanf("%s%s",&a1,&b1); if(a1[0] == '0' && b1[0] == '0') { cout << "0"; return 0; } for(int i = 0;i < strlen(a1);++i) a[strlen(a1) - i - 1] = a1[i] - '0'; for(int i = 0;i < strlen(b1);++i) b[strlen(b1) - i - 1] = b1[i] - '0'; m = max(strlen(a1),strlen(b1)); for(int i = 0;i < m;++i) c[i] = a[i] + b[i]; for (int i = 0;i <= m;++i) { c[i + 1] = c[i + 1] + c[i] / 10; c[i] = c[i] % 10; } m++; while(!c[m]) m--; for(int i = m;i >= 0;--i) cout << c[i]; return 0; }
高精度减法:
int main() { scanf("%s%s",&x,&y); int lena = strlen(x),lenb = strlen(y); for(int i = 0;i < lena;++i) a[lena - i - 1] = x[i] - '0'; for(int i = 0;i < lenb;++i) b[lenb - i - 1]=y[i] - '0'; if(lena > lenb) vis = 1; if(lena < lenb) vis = 0; if(lena == lenb) { string temp1 = x,temp2 = y; if(temp1 > temp2) vis = 1; if(temp1 == temp2) vis = 1; else vis = 0; } m = max(lena,lenb); if(vis) { for(int i = 0;i < m;++i) c[i]=a[i]-b[i]; } else { for(int i = 0;i < m;++i) c[i]=b[i]-a[i]; } for(int i = 0;i <= m;++i) { if(c[i] < 0){ c[i] += 10; c[i + 1]--; } } temp = m; for(int i = m;i >= 0;--i) { if(c[i]) break; temp--; if(i == 0 && c[i] == 0) { temp = 0; break; } } if(!vis) cout << "-"; for(int i = temp;i >= 0;--i) cout << c[i]; return 0; }
高精度乘法:
int main() { scanf("%s%s",&x,&y); int lena = strlen(x),lenb = strlen(y); for(int i = 0;i < lena;++i) a[lena - i - 1] = x[i] - '0'; for(int i = 0;i < lenb;++i) b[lenb - i - 1] = y[i] - '0'; for(int i = 0;i < lena;++i) for(int j = 0;j < lenb;++j) { c[i + j] += a[i] * b[j]; c[i + j + 1] += c[i+j] / 10; c[i + j] %= 10; } int lenc = lena + lenb; while(lenc > 1 && c[lenc - 1] == 0) lenc--; lenc--; for(int i = lenc;i >= 0;--i) cout << c[i]; return 0; }
数学
快速幂:
LL power(LL a,LL b) { LL t = 1,y = a; while(b) { if (b & 1) t = t * y % k; y = y * y % k; b >>= 1; } return t; }
埃式素数判定:
bool is_prime(int x) { if(x == 1 || x == 0) return false; for(int i = 2;i * i <= x;++i) if(x % i == 0) return false; return true; }
欧拉筛素数:
void is_prime(int list) { memset(vis,true,sizeof vis); vis[0] = vis[1] = false; for(int i = 2;i <= list;++i){ if(vis[i]) prime[++tot] = i; for(int j = 1;j <= list && i * prime[j] <= list;++j){ vis[i * prime[j]] = false; if(i % prime[j] == 0) break; } } }
欧几里得算法:
int gcd(int a,int b) { if(!b) return a; else return gcd(b,a % b); }
拓展欧几里得:
void ex_gcd(int &x,int &y,int a,int b) { if(b == 0) { y = 0; x = 1; } else { ex_gcd(y,x,b,a % b); y -= x * (a / b); } }
欧拉函数:
int euler(int n) { int res = n; for(int i = 2;i * i <= n;++i) { if(n % i == 0) res = res / i * (i - 1); while(n % i == 0) n /= i; } if(n > 1) res = res / n * (n - 1); return res; }
线性筛欧拉函数:
void get_phi(int list) { memset(vis,true,sizeof vis); vis[0] = vis[1] = false; phi[1] = 1; for(int i = 2;i <= list;++i){ if(vis[i]) prime[++tot] = i,phi[i] = i - 1; for(int j = 1;j <= list && i * prime[j] <= list;++j){ vis[i * prime[j]] = false; if(i % prime[j]) phi[i * prime[j]] = phi[i] * (prime[j] - 1); else { phi[i * prime[j]] = phi[i] * prime[j]; break; } } //phi[i] += phi[i - 1]; } }
矩阵运算:
inline Mat Mul(Mat a,Mat b){ Mat tmp; tmp.clear(); for(int i = 1;i <= n;++i) for(int j = 1;j <= n;++j) for(int k = 1;k <= n;++k) tmp.a[i][j] = (tmp.a[i][j] + (a.a[i][k] * b.a[k][j]) % MOD) % MOD; return tmp; } inline Mat power(Mat a,long long b){ Mat ans; ans.clear(); for(int i = 1;i <= n;++i) ans.a[i][i]=1; while(b){ if (b & 1) ans = Mul(ans,a); a = Mul(a,a); b >>= 1; } return ans; } inline Mat Add(Mat T_1,Mat T_2) { Mat Tmp; Tmp.clear(); for(int i = 1;i <= n;++i) for(int j = 1;j <= n;++j) Tmp.a[i][j] = T_1.a[i][j] + T_2.a[i][j],Tmp.a[i][j] %= MOD; return Tmp; }
图论
SPFA算法:
void Spfa() { queue <int > Q; Q.push(s); vis[s] = true; memset(dis,0x3f,sizeof dis); dis[s] = 0; while(!Q.empty()) { int u = Q.front(); Q.pop(); vis[u] = false; for(int i = head[u];i;i = e[i].nxt) { int v = e[i].to; if(dis[v] > dis[u] + e[i].dis) { dis[v] = dis[u] + e[i].dis; if(!vis[v]) { Q.push(v); vis[v] = true; } } } } }
Dijkstra算法:
void Dijkstra() { memset(dis,0x3f,sizeof dis); dis[s] = 0; priority_queue <pair <int ,int >,vector <pair <int ,int > >,greater <pair <int ,int > > > Q; Q.push(make_pair(0,s)); while(!Q.empty()) { int u = Q.top().second; Q.pop(); if(vis[u]) continue; vis[u] = true; for(int i = head[u];i;i = e[i].nxt) { int v = e[i].to; if(dis[v] > dis[u] + e[i].dis) { dis[v] = dis[u] + e[i].dis; if(!vis[v]) Q.push(make_pair(dis[v],v)); } } } }
最短路计数:
void Dijkstra_Heap() { priority_queue <pair <int ,int > ,vector <pair <int ,int > >,greater <pair <int ,int > > > Q; memset(dis,0x3f,sizeof dis); dis[s] = 0; ans[1] = 1; Q.push(make_pair(0,s)); while(!Q.empty()) { int u = Q.top().second; Q.pop(); if(vis[u]) continue; vis[u] = true; for(int i = head[u];i;i = e[i].nxt) { int v = e[i].to; if(dis[v] > dis[u] + 1) { dis[v] = dis[u] + 1; ans[v] = ans[u]; if(!vis[v]) Q.push(make_pair(dis[v],v)); } else if(dis[v] == dis[u] + 1) { ans[v] += ans[u]; ans[v] %= MOD; } } } }
负环:
bool spfa() { queue <int > Q; memset(&vis,false,sizeof vis); memset(&num,0,sizeof num); memset(&dis,0,sizeof dis); memset(&head,0,sizeof head); memset(&e,0,sizeof e); int n,m; scanf("%d%d",&n,&m); for(int i = 1;i <= m;++i) { int f,t,d; scanf("%d%d%d",&f,&t,&d); if(d < 0) { add(f,t,d); } else { add(f,t,d); add(t,f,d); } } memset(dis,0x3f,sizeof dis); dis[1] = 0; Q.push(1); vis[1] = true; while(!Q.empty()) { int u = Q.front(); Q.pop(); vis[u] = false; for(int i = head[u];i;i = e[i].nxt) { int v = e[i].to; if(dis[v] > dis[u] + e[i].dis) { dis[v] = dis[u] + e[i].dis; num[v] = num[u] + 1; if(num[v] >= n) return true; if(!vis[v]) { Q.push(v); vis[v] = true; } } } } return false; }
Tarjan割点:
void Tarjan(int u,int fa) { dfn[u] = low[u] = ++cmt; int child = 0; for(int i = head[u];i;i = e[i].next) { int v = e[i].to; if(!dfn[v]) { Tarjan(v,fa); low[u] = min(low[u],low[v]); if(low[v] >= dfn[u] && u != fa) cut[u] = true; if(u == fa) child++; } else low[u] = min(low[u],dfn[v]); } if(u == fa && child >= 2) cut[fa]=true; }
Tarjan强连通分量(缩点):
匈牙利算法:
bool dfs(int u) { for(int i = head[u];i;i = e[i].next) { int v = e[i].to; if(!used[v]) { used[v] = true; if(!Matched[v] || dfs(Matched[v])) { Matched[v] = u; return true; } } } return false; }
倍增LCA:
inline void dfs(int now,int f) { deepth[now] = deepth[f] + 1; fa[now][0] = f; for(int i = 1;(1 << i) <= deepth[now];++i) fa[now][i] = fa[fa[now][i - 1]][i - 1]; for(int i = head[now];i;i = e[i].next) { int v = e[i].to; if(v != f) dfs(v,now); } } inline int get_lca(int x,int y) { if(deepth[x] < deepth[y]) swap(x,y); while(deepth[x] > deepth[y]) x = fa[x][lg[deepth[x] - deepth[y]] - 1]; if(x == y) return x; for(int k = lg[deepth[x]];k >= 0;--k) if(fa[x][k] != fa[y][k]) x = fa[x][k],y = fa[y][k]; return fa[x][0]; } inline void Init() { for(int i = 1;i <= n;++i) lg[i] = lg[i >> 1] + 1; }
Kruskal算法:
int find(int x){ if(fa[x] != x) fa[x] = find(fa[x]); return fa[x]; } bool cmp(node a,node b){ return a.w < b.w; } void Kruskal() { for(int i = 1;i <= n;i++) fa[i] = i; sort(a + 1,a + 1 + m,cmp); for(int i = 1;i <= m;++i){ int fx = find(a[i].x); int fy = find(a[i].y); if(rand() & 1) swap(fx,fy); if(fx == fy) continue; ans += a[i].w; fa[fy] = fx; cnt++; if(cnt == n - 1) break; } }
Prim算法:
void Prim_Heap(int s) { memset(dis,0x3f,sizeof dis); memset(vis,false,sizeof vis); priority_queue <pair <int ,int >, vector < pair <int ,int > >, greater < pair <int ,int > > > Q; dis[s] = 0; Q.push(make_pair(0,s)); while(!Q.empty()) { int u = Q.top().second; int d = Q.top().first; Q.pop(); if(vis[u]) continue; num++; sum += d; vis[u] = true; for(int i = head[u];i;i = e[i].next) { int v = e[i].to; if(dis[v] > e[i].dis) { dis[v] = e[i].dis; Q.push(make_pair(dis[v],v)); } } } }
数据结构
一维树状数组:
void add(int x,int t) { while(x <= n) { v[x] += t; x += lowbit(x); } } int query(int x) { int res = 0; while(x) { res += v[x]; x -= lowbit(x); } return res; }
二维树状数组:
void add(int x,int y,int t) { while(x <= n) { for(int k = y;k <= m;k += lowbit(k)) v[x][k] += t; x += lowbit(x); } } int query(int x,int y) { int res = 0; while(x) { for(int k = y;k;k -= lowbit(k)) res += v[x][k]; x -= lowbit(x); } return res; }
线段树1(单点修改,区间查询):
void push_up(LL k) { tree[k] = tree[ls(k)] + tree[rs(k)]; } inline void f(LL k,LL l,LL r,LL p) { tag[k] += p; tree[k] += p * (r - l + 1); } void push_down(LL k,LL l,LL r) { LL mid = (l + r) >> 1; f(ls(k),l,mid,tag[k]); f(rs(k),mid + 1,r,tag[k]); tag[k] = 0; } void build(LL k,LL l,LL r) { tag[k] = 0; if(l == r) { tree[k] = a[l]; return ; } LL mid = (l + r) >> 1; build(ls(k),l,mid); build(rs(k),mid + 1,r); push_up(k); } void update(LL k,LL l,LL r,LL x,LL y,LL p) { if(y < l || x > r) return ; if(x <= l && y >= r) { tree[k] += p * (r - l + 1); tag[k] += p; return ; } push_down(k,l,r); LL mid = (l + r) >> 1; if(x <= mid) update(ls(k),l,mid,x,y,p); if(y > mid) update(rs(k),mid + 1,r,x,y,p); push_up(k); } LL Query(LL k,LL l,LL r,LL x,LL y) { LL res = 0; if(y < l || x > r) return 0; if(x <= l && y >= r) return tree[k]; LL mid = (l + r) >> 1; push_down(k,l,r); if(x <= mid) res += Query(ls(k),l,mid,x,y); if(y > mid) res += Query(rs(k),mid + 1,r,x,y); return res; }
线段树2(单点修改,区间查询):
void push_up(LL k) { tree[k] = tree[ls(k)] + tree[rs(k)]; tree[k] %= MOD; } inline void f(LL k,LL l,LL r,LL p) { tree[k] += p * (r - l + 1); tree[k] %= MOD; tag[k] += p; tag[k] %= MOD; } void f_2(LL k,LL l,LL r,LL p) { tree[k] *= p; tree[k] %= MOD; tag[k] *= p; tag[k] %= MOD; tag2[k] *= p; tag2[k] %= MOD; } void push_down(LL k,LL l,LL r) { LL mid = (l + r) >> 1; if(tag2[k] != 1) { f_2(ls(k),l,mid,tag2[k]); f_2(rs(k),mid + 1,r,tag2[k]); tag2[k] = 1; } if(tag[k]) { f(ls(k),l,mid,tag[k]); f(rs(k),mid + 1,r,tag[k]); tag[k] = 0; } } void build(LL k,LL l,LL r) { tag[k] = 0; tag2[k] = 1; if(l == r) { tree[k] = a[l]; return ; } LL mid = (l + r) >> 1; build(ls(k),l,mid); build(rs(k),mid + 1,r); push_up(k); } void Update_Add(LL k,LL l,LL r,LL x,LL y,LL p) { if(y < l or x > r) return ; if(l >= x and r <= y) { tag[k] += p; tag[k] %= MOD; tree[k] += p * (r - l + 1); tree[k] %= MOD; return ; } push_down(k,l,r); LL mid = (l + r) >> 1; if(x <= mid) Update_Add(ls(k),l,mid,x,y,p); if(y > mid) Update_Add(rs(k),mid + 1,r,x,y,p); push_up(k); } LL Query(LL k,LL l,LL r,LL x,LL y) { if(y < l or x > r) return 0; if(l >= x and r <= y) return tree[k]; push_down(k,l,r); LL mid = (l + r) >> 1; LL res = 0; if(x <= mid) res = (res + Query(ls(k),l,mid,x,y)) % MOD; if(y > mid) res = (res + Query(rs(k),mid + 1,r,x,y)) % MOD; return res % MOD; } void Update_Cheng(LL k,LL l,LL r,LL x,LL y,LL p) { if(y < l or x > r) return ; if(l >= x and r <= y) { tag[k] *= p; tag[k] %= MOD; tree[k] *= p; tree[k] %= MOD; tag2[k] *= p; tag2[k] %= MOD; return ; } push_down(k,l,r); LL mid = (l + r) >> 1; if(x <= mid) Update_Cheng(ls(k),l,mid,x,y,p); if(y > mid) Update_Cheng(rs(k),mid + 1,r,x,y,p); push_up(k); }
ST表:
void Init() { lg[0] = -1; for(int i = 1;i <= n;++i) lg[i] = lg[i >> 1] + 1; for(int i = 1;i <= n;++i) scanf("%d",&Max[i][0]); for(int i = 1;i <= n;++i) Min[i][0] = Max[i][0]; for(int j = 1;j <= 21;++j) for(int i = 1;i + (1 << j) - 1 <= n;++i) { Max[i][j] = max(Max[i][j - 1],Max[i + (1 << (j - 1))][j - 1]); Min[i][j] = min(Min[i][j - 1],Min[i + (1 << (j - 1))][j - 1]); } } int QueryMax(int l,int r) { int k = lg[r - l + 1]; return max(Max[l][k],Max[r - (1 << k) + 1][k]); } int QueryMin(int l,int r) { int k = lg[r - l + 1]; return min(Min[l][k],Min[r - (1 << k) + 1][k]); }
并查集:
void Init() { for(int i = 1;i <= n;++i) father[i] = i; } int Find(int x) { if(x != father[x]) father[x] = Find(father[x]); return father[x]; }
分块:以后会整理分块入门1-9
字符串算法:
Manacher算法:
int Init() { //初始化并返回new_s长度 int len = strlen(s); new_s[0] = '$'; new_s[1] = '#'; int j = 2; for(int i = 0; i < len;++i) { new_s[j++] = s[i]; new_s[j++] = '#'; } new_s[j] = '\0'; return j; } int Manacher() { int len = Init(); int max_len = -1; int id = 0,mx = 0; for(int i = 1;i < len;++i) { if(i < mx) p[i] = min(p[2 * id - i],mx - i); // 2 * id - i指i关于id的对称点j else p[i] = 1; while(new_s[i - p[i]] == new_s[i + p[i]]) p[i]++; if(mx < i + p[i]) { id = i; mx = i + p[i]; } max_len = max(max_len,p[i] - 1); } return max_len; }
KMP算法:
void kmp1() { int j = 0; for(int i = 2;i <= lenb;++i) { while(j && b[j + 1] != b[i]) j = next[j]; if(b[j + 1] == b[i]) j++; next[i] = j; } } void kmp2() { int j = 0; for(int i = 1;i <= lena;++i) { while(j && b[j + 1] != a[i]) j = next[j]; if(b[j + 1] == a[i]) j++; if(j == lenb) { cout << i - lenb + 1 <<endl; j = next[j]; } } }
Hash:
const int Base = 131; const int Prime = 19260817; const LL MOD = 212370440130137957ll; LL hash(char s[]) { int len = strlen(s); LL cnt = 0; for(int i = 0;i < len;++i) cnt = (cnt * Base + (LL)s[i]) % MOD + Prime; return cnt; }
文章评论
lz可以加个qq沟通交流一下吗pwp