intget_phi(){for(int i =1; i <= Maxn;++i) phi[i]= i;for(int i =2; i <= Maxn;++i)if(phi[i]== i){for(int j = i; j <= x; j += i)
phi[j]-= phi[j]/ i;}}
欧拉函数#2
voidget_phi(){
phi[1]=1;for(int i =2; i <= Maxn;++i){if(!phi[i]){
phi[i]= i -1;
prime[++cnt]= i;}for(int j =1; j <= cnt && i * prime[j]<= Maxn;++j){if(i % prime[j]==0){
phi[i * prime[j]]= phi[i]* prime[j];break;}else phi[i * prime[j]]= phi[i]* phi[prime[j]];}}for(int i =3; i <= Maxn;++i)
phi[i]+= phi[i -1];}
欧拉函数#3
voidget_phi(int n){int res = n;for(int i =2; i <= n / i ; 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;}
扩展欧几里得
intex_gcd(int a,int b,int&x,int&y){if(b ==0){
x = n / a; y =0;return a;}else{int r =ex_gcd(b, a % b, x, y);int t = x;
x = y;
y = t - a / b * y;return r;}}
逆元
inv[1]=1;for(int i =2; i <= n;++i){
inv[i]=(p - p / i)* inv[p % i]% p;}
中国剩余定理(n组余数关系)
cin >> n;for(int i =1; i <= n;++i){
cin >> a[i]>> b[i];
sum = sum * a[i];}for(int i =1; i <= n;++i){
sum /= a[i];
x = y =0;ex_gcd(sum, a[i], x, y);//求逆元,使余数归一
x =(x + a[i])% a[i];
ans =(ans + x * sum * b[i])%(sum * a[i]);//通过相乘产生当前余数
sum *= a[i];}
cout << ans % sum << endl;
线性筛(同时统计最小因数)
for(int i =2; i <= n;++i) mindiv[i]= i;for(int i =2; i <= n;++i){if(mindiv[i]== i) prime[++cnt]= i;for(int j =1; j <= cnt && i * prime[j]<= n;++j){
mindiv[i * prime[j]]= prime[j];if(i % prime[j]==0)break;}}
最大公约数
intgcd(int x,int y){if(y ==0)return x;returngcd(y, x % y);}
intkruskal(){int m =0, ans =0;for(int i =0; i < n;++i)
fa[i]= i;for(int i =1; i <= js;++i){int fu =find(edg[i].u);int fv =find(edg[i].v);if(fu != fv){
ans += edg[i].w;
fa[fu]= fv;
m++;if(m == n -1)break;}}return ans;}
Prim
intprim(){for(int i =0; i < n;++i){
dis[i]= g[1][i];}memset(vis,0,sizeof(vis));
vis[1]=true;int ans =0, pv;for(int i =1; i < n;++i){int minv =0x3f3f3f3f;for(int j =0; j < n;++j)if(!vis[j]&& dis[j]< minv){
minv = dis[j];
pv = j;}
ans += dis[pv];
vis[pv]=1;for(int j =0; j < n;++j)if(!vis[j]) dis[j]=min(dis[j], g[pv][j]);}return ans;}
Tarjan
#include<bits/stdc++.h>usingnamespace std;constint maxn =1e4+15;int n, m, sum, tim, top, s, p[maxn], head[maxn], sd[maxn], dfn[maxn], low[maxn], sta[maxn], vh[maxn], h[maxn], in[maxn], dis[maxn];structEdge{int to, next, from;}edge[maxn *10], ed[maxn *10];inlinevoidadd(int x,int y);inlineintTopu();inlinevoidTarjan(int x){
low[x]= dfn[x]=++tim;
sta[++top]= x;
vh[x]=1;for(int i = head[x]; i; i = edge[i].next){int v = edge[i].to;if(!dfn[v]){Tarjan(v);
low[x]=min(low[x], low[v]);}elseif(vh[v])
low[x]=min(low[x], low[v]);}if(dfn[x]== low[x]){int y;while(y = sta[top--]){
sd[y]= x;
vh[y]=0;if(x == y)break;
p[x]+= p[y];}}}intmain(){
ios::sync_with_stdio(false);
cin >> n >> m;for(int i =1; i <= n;++i)
cin >> p[i];for(int i =1; i <= m;++i){int u, v;
cin >> u >> v;add(u, v);}for(int i =1; i <= n;++i)if(!dfn[i])Tarjan(i);for(int i =1; i <= m;++i){int x = sd[edge[i].from], y = sd[edge[i].to];if(x != y){
ed[++s].next = h[x];
ed[s].to = y;
ed[s].from = x;
h[x]= s;
in[y]++;}}
cout <<Topu()<< endl;return0;}
SPFA
voidspfa(int s){
queue <int> que;memset(dis,0x3f3f3f3f,sizeof(dis));
dis[s]=0;
que.push(s);while(!que.empty()){int f = que.front();
que.pop();
vh[f]=0;for(int i =0; i < p[f].size();++i){
node v = p[f][i];if(dis[v.to]> dis[f]+ v.len){
dis[v.to]= dis[f]+ v.len;if(!vh[v.to]){
vh[v.to]=1;
que.push(v.to);}}}}}//统计每个点入队次数可以判断有无负回路
Dijkstra
structnode{int to, len;booloperator<(const node x)const{return len > x.len;}};voiddijkstra(int s){
priority_queue <node> que;memset(dis,0x3f3f3f3f,sizeof(dis));
dis[s]=0;
que.push({s,0});while(!que.empty()){
node f = que.top();
que.pop();if(f.len > dis[f.to])continue;for(int i =0; i < p[f.to].size();++i){
node v = p[f.to][i];if(dis[f.to]+ v.len < dis[v.to]){
dis[v.to]= dis[f.to]+ v.len;
que.push({v.to, dis[v.to]});}}}}
Floyd
voidfloyd(){//记得读入的时候去重边(CSP-S T3悲)for(int i =1; i <= n;++i)
dis[i][i]=0;for(int k =1; k <= n;++k)for(int i =1; i <= n;++i)for(int j =1; j <= n;++j)
dis[i][j]=min(dis[i][j], dis[i][k]+ dis[k][j]);}
拓扑排序
inlineintTopu(){
queue <int> q;int tot =0;for(int i =1; i <= n;++i)if(sd[i]== i &&!in[i]){//此处在缩点之后使用,所以会有这个数组
q.push(i);
dis[i]= p[i];}while(!q.empty()){registerint k = q.front();
q.pop();for(registerint i = h[k]; i; i = ed[i].next){registerint v = ed[i].to;
dis[v]=max(dis[v], dis[k]+ p[v]);
in[v]--;if(in[v]==0)
q.push(v);}}int ans =0;for(int i =1; i <= n;++i)
ans =max(ans, dis[i]);return ans;}
割点
树的直径
数据结构
STL
Set
set <data_type> set_name;
set <data_type>::iterator it = the_position_you_want
for(int i =1; i <= n;++i)
cin >> f[i][0];
lg[1]=0;for(int i =2; i <= n;++i)
lg[i]= lg[i /2]+1;for(int j =1; j <= lg[n];++j)for(int i =1; i +(1<< j)-1<= n;++i)
f[i][j]=max(f[i][j -1], f[i +(1<<(j -1))][j -1]);int l, r;for(int i =1; i <= m;++i){
cin >> l >> r;int p = r - l +1;
cout <<max(f[l][lg[p]], f[r -(1<< lg[p])+1][lg[p]])<< endl;}
链表
#include<bits/stdc++.h>usingnamespace std;structnode{int val, next;};
node a[110];int n, head;intmain(){
cin >> n;
a[head].next =-1;for(int i =1; i <= n;++i){
cin >> a[i].val;int p = head;while(a[p].next !=-1&& a[a[p].next].val < a[i].val)
p = a[p].next;
a[i].next = a[p].next;
a[p].next = i;}int p = a[head].next;while(p !=-1){
cout << a[p].val <<" ";
p = a[p].next;}
cout << endl;return0;}
LCA
voiddfs(int k,int f){//f:fa
fa[k][0]= f;
d[k]= d[f]+1;for(int i =1;(1<< i)<= d[k];++i)
fa[k][i]= fa[fa[k][i -1]][i -1];for(int i =0; i < g[k].size();++i){if(g[k][i]== f)continue;dfs(g[k][i], k);}}intLCA(int x,int y){if(d[x]> d[y])swap(x, y);for(int i =19; i >=0;--i)if((1<< i)+ d[x]<= d[y]) y = fa[y][i];if(x == y)return x;for(int i =19; i >=0;--i){if(fa[x][i]!= fa[y][i]){
x = fa[x][i];
y = fa[y][i];}}return fa[x][0];}
基础算法
二分
快速排序
#include<bits/stdc++.h>usingnamespace std;int n, a[100100];voidquick_sort(int l,int r){int x, i, j;
i = l;
j = r;
x = a[(i + j)/2];do{while(a[i]< x) i++;while(a[j]> x) j--;if(i <= j){swap(a[i], a[j]);
i++; j--;}}while(i <= j);if(i < r)quick_sort(i, r);if(j > l)quick_sort(l, j);}intmain(){
cin >> n;for(int i =1; i <= n;++i)
cin >> a[i];quick_sort(1, n);for(int i =1; i < n;++i)
cout << a[i]<<" ";
cout << a[n]<< endl;return0;}
structlarge{int val[10010], len =0;voidinput(){
string s;
cin >> s;for(len =0; len < s.size();++len)
val[s.size()- len]= s[len]-'0';}voidoutput(){for(int i = len; i >=1;--i)
cout << val[i];}booloperator<(const large &x)const{if(len > x.len)returnfalse;for(int i =1; i < len;++i)if(val[i]> x.val[i])returnfalse;if(val[len]== x.val[len])returnfalse;returntrue;}booloperator>(const large &x)const{if(len < x.len)returnfalse;for(int i =1; i < len;++i)if(val[i]< x.val[i])returnfalse;if(val[len]== x.val[len])returnfalse;returntrue;}booloperator==(const large &x)const{if(len != x.len)returnfalse;for(int i =1; i <= len;++i)if(val[i]!= x.val[i])returnfalse;returntrue;}
large operator+(const large &x)const{
large ans;
ans.len =max(len, x.len);for(int i =1; i <= ans.len;++i)
ans.val[i]= val[i]+ x.val[i];for(int i =1; i <= ans.len;++i){if(ans.val[i]/10){
ans.val[i +1]+= ans.val[i]/10;
ans.val[i]%=10;}if(i == ans.len && ans.val[i +1]) ans.len++;}return ans;}
large operator-(const large &x)const{
large ans;
ans.len =max(len, x.len);for(int i =1; i <= ans.len;++i)
ans.val[i]= val[i]- x.val[i];for(int i =1; i <= ans.len;++i){if(ans.val[i]<0){
ans.val[i +1]--;
ans.val[i]+=10;}}while(ans.len >1&&!ans.val[ans.len]) ans.len--;return ans;}
large operator*(const large & x)const{
large ans;
ans.len = len + x.len -1;for(int i =1; i <= len;++i)for(int j =1; j <= x.len;++j)
ans.val[i + j -1]+= val[i]* x.val[j];for(int i =1; i <= ans.len;++i){if(ans.val[i]/10){
ans.val[i +1]+= ans.val[i]/10;
ans.val[i]%=10;}if(i == ans.len && ans.val[i +1]) ans.len++;}while(ans.len >1&&!ans.val[ans.len]) ans.len--;return ans;}//I hate dividing very much!!};
快速幂
intqm(int x,int y,int d){if(y ==0|| x ==1)return1;if(y ==1)return x % d;int num =qm(x, y /2, d);if(y %2)return(((num * num)% d)*(x % d))% d;elsereturn(num * num)% d;}
#include<bits/stdc++.h>usingnamespace std;structnum{int val, id;}a[100010];int n, pos, p_map[100010], ans[50010], nxt[100010], pre[100010];boolcmp(num x, num y){return x.val < y.val;}intmain(){
cin >> n;if(!(n %2)) n--;for(int i =1; i <= n;++i){
cin >> a[i].val;
a[i].id = i;}sort(a +1, a +1+ n, cmp);for(int i =1; i <= n;++i)
p_map[a[i].id]= i;for(int i =1; i <= n;++i){
pre[i]= i -1;
nxt[i]= i +1;}
pre[1]= nxt[n]=-1;int pos =(n +1)/2, cnt;for(cnt =1; cnt *2< n;++cnt){
ans[cnt]= a[pos].val;int p1 = p_map[n - cnt *2+1], p2 = p_map[n - cnt *2+2];if(pre[p1]!=-1) nxt[pre[p1]]= nxt[p1];if(nxt[p1]!=-1) pre[nxt[p1]]= pre[p1];if(pre[p2]!=-1) nxt[pre[p2]]= nxt[p2];if(nxt[p2]!=-1) pre[nxt[p2]]= pre[p2];if(p1 >= pos && p2 >= pos) pos = pre[pos];if(p1 <= pos && p2 <= pos) pos = nxt[pos];}
ans[cnt]= a[pos].val;for(int i = cnt; i >=1;--i)
cout << ans[i]<< endl;return0;}
最长公共子序列
#include<bits/stdc++.h>usingnamespace std;int n, p1[100010], p2[100010], trans[100010], dp[100010], ans =0;intef(int x){int l =0, r = n;while(l < r){int mid =(l + r)/2;if(dp[mid]== x) l = mid +1;if(dp[mid]> x) r = mid;if(dp[mid]< x) l = mid +1;}return l;}intmain(){memset(dp,0x3f3f3f3f,sizeof(dp));
cin >> n;for(int i =1; i <= n;++i)
cin >> p1[i];for(int i =1; i <= n;++i)
cin >> p2[i];for(int i =1; i <= n;++i)
trans[p1[i]]= i;for(int i =1; i <= n;++i)
p2[i]= trans[p2[i]];
dp[1]= p2[1]; dp[0]=0;for(int i =2; i <= n;++i){int pos =ef(p2[i]);
dp[pos]= p2[i];
ans =max(ans, pos);}//最长不下降子序列
cout << ans << endl;return0;}
玄学
文件比较指令
cd\ //进入C盘
fc original_data.out output_data.out
快读
inlineintread(){registerint x =0,f =1;registerchar ch =getchar();while(ch <'0'|| ch >'9'){if(ch =='-') f =-1;
ch =getchar();}while(ch >='0'&& ch <='9'){
x = x *10+ ch -'0';
ch =getchar();}return x * f;}