模板整理計劃
阿新 • • 發佈:2019-01-10
“是時候了”
“好”
“我來了” “NOIp”
全排列
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAXN (100)
int n;
int num[MAXN];
bool vis[MAXN];
void print()
{
for(int i = 1; i <= n; ++ i)
printf("%d ", num[i]);
cout << '\n';
}
void dfs(int x)
{
if(x > n)
{
print();
return;
}
for(int i = 1; i <= n; ++ i)
{
if(!vis[i])
{
num[x] = i;
vis[i] = 1;
dfs(x+1);
vis[i] = 0;
}
}
}
int main()
{
cin >> n;
dfs(1);
return 0;
}
選數半排列
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAXN (100)
int n, k;
int num[MAXN], ans[MAXN];
void print()
{
for(int i = 1; i <= k; ++ i)
printf("%d ", ans[i]);
cout << '\n';
}
void dfs(int x, int last)
{
if(x > k)
{
print();
return;
}
for(int i = last+1; i <= n; ++ i)
{
ans[x] = num[i];
dfs(x+1, i);
}
}
int main()
{
cin >> n >> k;
for(int i = 1; i <= n; ++ i)
scanf("%d", &num[i]);
dfs(1,0);
return 0;
}
DFS子集列舉
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAXN (100)
int n;
bool vis[MAXN];
void print()
{
for(int i = 1; i <= n; ++ i)
printf("%d ", vis[i]);
cout << '\n';
}
void dfs(int x)
{
if(x > n)
{
print();
return;
}
vis[x] = 0;
dfs(x+1);
vis[x] = 1;
dfs(x+1);
vis[x] = 0;
}
int main()
{
cin >> n;
dfs(1);
return 0;
}
二進位制子集列舉
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int n;
cin >> n;
for(int s = 0; s < (1<<n); ++ s)
{
for(int j = n-1; j >= 0; -- j)
cout << (bool)(s&(1<<j)) << " ";
cout << '\n';
}
return 0;
}
gcd
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
int gcd(int a, int b)
{
if(!b) return a;
return gcd(b,a%b);
}
int main()
{
int a, b;
cin >> a >> b;
cout << gcd(max(a,b),min(a,b));
return 0;
}
exgcd
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
int exgcd(int a, int b, int &x, int &y)
{
if(!b)
{
x = 1; y = 0;
return a;
}
int ans = gcd(b,a%b,x,y);
int t = x;
x = y;
y = t-a/b*y;
return ans;
}
int main()
{
int a, b, x, y;
cin >> a >> b;
cout << gcd(max(a,b),min(a,b),x,y) << " " << x << " " < y << '\n';
return 0;
}
埃氏篩法
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAXN (100000)
bool vis[MAXN];
int main()
{
int n;
cin >> n;
for(int i = 2; i <= n; ++ i)
if(!vis[i])
for(int j = i+i; j <= n; j += i)
vis[j] = 1;
for(int i = 2; i <= n; ++ i)
if(!vis[i])
printf("%d ", i);
printf("\n");
return 0;
}
尤拉篩法-線性篩
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAXN (100000)
bool vis[MAXN];
int prime[MAXN];
int main()
{
int n, cnt = 0;
cin >> n;
fill(vis+1, vis+n+1, 1);
for(int i = 2; i <= n; ++ i)
{
if(vis[i]) prime[++cnt] = i;
for(int j = 1; j <= cnt && prime[j]*i <= n; ++ j)
{
vis[prime[j]*i] = 0;
if(i%prime[j] == 0) break;
}
}
for(int i = 1; i <= cnt; ++ i)
printf("%d ", prime[i]);
printf("\n");
return 0;
}
快速冪(非遞迴)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
typedef long long LL;
LL ksm(LL a, LL p, LL k)
{
LL ans = 1;
for(; p; p >>= 1, a = ((a%k)*(a%k))%k)
if(p&1)
ans = ((ans%k)*(a%k))%k;
return ans%k;
}
int main()
{
LL a, b, c;
cin >> a >> b >> c;
printf("%lld^%lld mod %lld=%lld\n",a, b, c, ksm(a,b,c));
return 0;
}
暴力LCA(帶DFS+邊權)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAX_V (500000)
#define MAX_E (MAX_V)
int V, tot = 0;
int first[MAX_V], nxt[MAX_E<<1], deep[MAX_V], fa[MAX_V], dis[MAX_V];
struct edge{
int from, to, cost;
}es[MAX_E<<1];
void build(int ff, int tt, int dd)
{
es[++tot] = (edge){ff,tt,dd};
nxt[tot] = first[ff];
first[ff] = tot;
}
void dfs(int x, int f)
{
fa[x] = f;
deep[x] = deep[f]+1;
for(int i = first[x]; i != -1; i = nxt[i])
{
int v = es[i].to;
if(v == f) continue;
dis[v] = es[i].cost;
dfs(v,x);
}
}
int lca(int x, int y)
{
int ans = 0;
if(deep[x] > deep[y]) swap(x,y);
while(deep[y] != deep[x])
{
ans += dis[y];
y = fa[y];
}
while(x != y)
{
ans += dis[x];
x = fa[x];
ans += dis[y];
y = fa[y];
}
return ans;
}
int main()
{
cin >> V;
memset(first,-1,sizeof(first));
for(int i = 1; i < V; ++ i)
{
int f, t, d;
scanf("%d%d%d", &f, &t, &d);
build(f,t,d); build(t,f,d);
}
deep[1] = 0; dis[1] = 0;
dfs(1,1);
int Q;
cin >> Q;
while(Q --)
{
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", lca(x,y));
}
return 0;
}
並查集
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAXN (10010)
int fa[MAXN];
int find(int x)
{
int t, r = x;
while(r != fa[r]) r = fa[r];
while(x != r) {t=fa[x];fa[x]=r;x=t;}
return r;
}
void lianjie(int x, int y)
{
int fx = find(x), fy = find(y);
if(fx != fy) fa[fx] = fy;
}
void check(int x, int y)
{
int fx = find(x), fy = find(y);
if(fx != fy) puts("N");
else puts("Y");
}
int main()
{
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; ++ i) fa[i] = i;
for(int i = 1; i <= m; ++ i)
{
int t, x, y;
scanf("%d%d%d", &t, &x, &y);
if(t == 1) lianjie(x,y);
else check(x,y);
}
return 0;
}
最小生成樹Kruskal
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define MAX_V (5050)
#define MAX_E (200200)
int V, E;
int fa[MAX_V];
struct edge{
int from, to, cost;
}es[MAX_E];
bool cmp(edge a, edge b) {return a.cost < b.cost;}
int find(int x)
{
int t, r = x;
while(r != fa[r]) r = fa[r];
while(x != r){t=fa[x];fa[x]=r;x=t;}
return r;
}
int kruskal()
{
int ans = 0;
for(int i = 1; i <= V; ++ i) fa[i] = i;
sort(es+1, es+E+1, cmp);
for(int i = 1; i <= E; ++ i)
{
int fu = find(es[i].from);
int fv = find(es[i].to);
if(fu != fv)
{
fa[fu] = fv;
ans += es[i].cost;
}
}
return ans;
}
int main()
{
cin >> V >> E;
for(int i = 1; i <= E; ++ i)
{
int f, t, d;
scanf("%d%d%d", &f, &t, &d);
es[i] = (edge){f,t,d};
}
cout << kruskal() << '\n';
return 0;
}
最短路floyd
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define MAXN (110)
int V;
int dis[MAXN][MAXN];
void floyd()
{
for(int k = 1; k <= V; ++ k)
for(int i = 1; i <= V; ++ i)
for(int j = 1; j <= V; ++ j)
dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]);
}
int main()
{
cin >> V;
memset(dis,63,sizeof(dis));
for(int i = 1; i <= V; ++ i)
for(int j = 1; j <= V; ++ j)
scanf("%d", &dis[i][j]), dis[j][i] = dis[i][j];
floyd();
int Q; cin >> Q;
while(Q--)
{
int a, b;
scanf("%d%d", &a, &b);
printf("%d\n", dis[a][b]);
}
return 0;
}
最短路spfa
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <queue>
using namespace std;
#define MAX_V (2525)
#define MAX_E (6262)
int V, E, tot = 0;
int first[MAX_V], nxt[MAX_E<<1], dis[MAX_V];
bool used[MAX_V];
struct edge{
int from, to, cost;
}es[MAX_E<<1];
void build(int ff, int tt, int dd)
{
es[++tot] = (edge){ff,tt,dd};
nxt[tot] = first[ff];
first[ff] = tot;
}
#define INF (1e9)
queue <int> q;
void spfa(int s)
{
fill(dis+1,dis+V+1,INF);
dis[s] = 0;
q.push(s);
used[s] = 1;
while(q.size())
{
int x = q.front();
q.pop();
used[x] = 0;
for(int i = first[x]; i != -1; i = nxt[i])
{
int v = es[i].to;
if(dis[v] > dis[x] + es[i].cost)
{
dis[v] = dis[x] + es[i].cost;
if(!used[v])
{
q.push(v);
used[v] = 1;
}
}
}
}
}
int main()
{
int Ts, Te;
cin >> V >> E >> Ts >> Te;
memset(first,-1,sizeof(first));
for(int i = 1; i <= E; ++ i)
{
int f, t, d;
scanf("%d%d%d", &f, &t, &d);
build(f,t,d); build(t,f,d);
}
spfa(Ts);
cout << dis[Te] << '\n';
return 0;
}
最短路spfa_slf優化
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <queue>
using namespace std;
#define MAX_V (2525)
#define MAX_E (6262)
int V, E, tot = 0;
int first[MAX_V], nxt[MAX_E<<1], dis[MAX_V];
bool used[MAX_V];
struct edge{
int from, to, cost;
}es[MAX_E<<1];
void build(int ff, int tt, int dd)
{
es[++tot] = (edge){ff,tt,dd};
nxt[tot] = first[ff];
first[ff] = tot;
}
#define INF (1e9)
deque <int> q;
void spfa_slf(int s)
{
fill(dis+1,dis+V+1,INF);
dis[s] = 0;
q.push_back(s);
used[s] = 1;
while(q.size())
{
int x = q.front();
q.pop_front();
used[x] = 0;
for(int i = first[x]; i != -1; i = nxt[i])
{
int v = es[i].to;
if(dis[v] > dis[x] + es[i].cost)
{
dis[v] = dis[x] + es[i].cost;
if(!used[v])
{
if(q.empty()) q.push_back(v);
else if(dis[v] <= dis[q.front()]) q.push_front(v);
else q.push_back(v);
used[v] = 1;
}
}
}
}
}
int main()
{
int Ts, Te;
cin >> V >> E >> Ts >> Te;
memset(first,-1,sizeof(first));
for(int i = 1; i <= E; ++ i)
{
int f, t, d;
scanf("%d%d%d", &f, &t, &d);
build(f,t,d); build(t,f,d);
}
spfa_slf(Ts);
cout << dis[Te] << '\n';
return 0;
}
最短路spfa判負環
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <queue>
using namespace std;
#define MAX_V (2525)
#define MAX_E (6262)
int V, E, EE, tot = 0;
int first[MAX_V], nxt[MAX_E<<1], dis[MAX_V];
bool used[MAX_V];
struct edge{
int from, to, cost;
}es[MAX_E<<1];
void build(int ff, int tt, int dd)
{
es[++tot] = (edge){ff,tt,dd};
nxt[tot] = first[ff];
first[ff] = tot;
}
#define INF (1e9)
queue <int> q;
int tim[MAX_V];
string spfa(int s)
{
fill(dis+1,dis+V+1,INF);
dis[s] = 0;
q.push(s);
used[s] = 1;
while(q.size())
{
int x = q.front();
q.pop();
used[x] = 0;
if(++tim[x] > V) return "YES";
for(int i = first[x]; i != -1; i = nxt[i])
{
int v = es[i].to;
if(dis[v] > dis[x] + es[i].cost)
{
dis[v] = dis[x] + es[i].cost;
if(!used[v])
{
q.push(v);
used[v] = 1;
}
}
}
}
return "NO";
}
int main()
{
int T;
cin >> T;
while(T --)
{
tot = 0;
memset(first,-1,sizeof(first));
memset(nxt,0,sizeof(nxt));
memset(used,0,sizeof(used));
memset(es,0,sizeof(es));
memset(tim,0,sizeof(tim));
while(q.size()) q.pop();
scanf("%d%d%d", &V, &E, &EE);
for(int i = 1; i <= E; ++ i)
{
int f, t, d;
scanf("%d%d%d", &f, &t, &d);
build(f,t,d); build(t,f,d);
}
for(int i = 1; i <= EE; ++ i)
{
int f, t, d;
scanf("%d%d%d", &f, &t, &d);
build(f,t,-d);
}
cout << spfa(1) << '\n';
}
return 0;
}
最短路 Dijsktra堆優化
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <queue>
using namespace std;
#define MAX_V (2525)
#define MAX_E (6262)
int V, E, tot = 0;
int first[MAX_V], nxt[MAX_E<<1], dis[MAX_V];
bool done[MAX_V];
struct edge{
int from, to, cost;
}es[MAX_E<<1];
void build(int ff, int tt, int dd)
{
es[++tot] = (edge){ff,tt,dd};
nxt[tot] = first[ff];
first[ff] = tot;
}
struct zt{
int u, d;
};
bool operator < (zt a, zt b)
{
return a.d > b.d;
}
priority_queue <zt> q;
#define INF (1e9)
void Dijkstra(int s)
{
fill(dis+1,dis+V+1,INF);
dis[s] = 0;
q.push((zt){s,0});
while(q.size())
{
int x = q.top().u;
q.pop();
if(done[x]) continue;
done[x] = 1;
for(int i = first[x]; i != -1; i = nxt[i])
{
int v = es[i].to;
if(dis[v] > dis[x] + es[i].cost)
{
dis[v] = dis[x] + es[i].cost;
q.push((zt){v,dis[v]});
}
}
}
}
int main()
{
int Ts, Te;
cin >> V >> E >> Ts >> Te;
memset(first,-1,sizeof(first));
for(int i = 1; i <= E; ++ i)
{
int f, t, d;
scanf("%d%d%d", &f, &t, &d);
build(f,t,d); build(t,f,d);
}
Dijkstra(Ts);
cout << dis[Te] << '\n';
return 0;
}
次短路_sub_spfa
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <queue>
using namespace std;
#define MAXN (100100)
int V, E, tot = 0;
int first[MAXN], nxt[MAXN<<1], dis1[MAXN], dis2[MAXN];
bool used[MAXN];
struct edge{
int from, to, cost;
}es[MAXN<<1];
void build(int ff, int tt, int dd)
{
es[++tot] = (edge){ff,tt,dd};
nxt[tot] = first[ff];
first[ff] = tot;
}
#define INF (1e9)
queue <int> q;
void sub_spfa(int s)
{
fill(dis1+1,dis1+V+1,INF); fill(dis2+1,dis2+V+1,INF);
dis1[s] = 0;
q.push(s);
used[s] = 1;
while(q.size())
{
int x = q.front();
q.pop();
used[x] = 0;
for(int i = first[x]; i != -1; i = nxt[i])
{
int v = es[i].to;
if(dis1[v] > dis1[x] + es[i].cost)
{
dis2[v] = dis1[v];
dis1[v] = dis1[x] + es[i].cost;
if(!used[v])
{
q.push(v);
used[v] = 1;
}
}
else if((dis1[v] < dis1[x]+es[i].cost) && (dis2[v] > dis1[x]+es[i].cost))
{
dis2[v] = dis1[x] + es[i].cost;
if(!used[v])
{
q.push(v);
used[v] = 1;
}
}
else if(dis2[v] > dis2[x] + es[i].cost)
{
dis2[v] = dis2[x] + es[i].cost;
if(!used[v])
{
q.push(v);
used[v] = 1;
}
}
}
}
}
int main()
{
cin >> V >> E;
memset(first,-1,sizeof(first));
for(int i = 1; i <= E; ++ i)
{
int f,t,d;
scanf("%d%d%d", &f, &t, &d);
build(f,t,d);
}
sub_spfa(1);
if(dis2[V] < INF) cout << dis2[V] << '\n';
else puts("-1");
return 0;
}
線段樹
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define SZ(x) (tree[x].r-tree[x].l+1)
using namespace std;
typedef long long LL;
#define MAXN (200020)
int xl[MAXN];
struct TREE{
int l, r, add;
LL sum;
}tree[MAXN<<2];
void update(int p)
{
tree[p].sum = tree[L(p)].sum + tree[R(p)].sum;
return;
}
void build(int l, int r, int p)
{
tree[p].l = l; tree[p].r = r;
if(l == r)
{
tree[p].sum = xl[l];
return;
}
int mid = (tree[p].l+tree[p].r)>>1;
build(l,mid,L(p)); build(mid+1,r,R(p));
update(p);
return;
}
void spread(int p)
{
if(tree[p].add)
{
tree[L(p)].add += tree[p].add;
tree[R(p)].add += tree[p].add;
tree[L(p)].sum += (SZ(L(p))*tree[p].add);
tree[R(p)].sum += (SZ(R(p))*tree[p].add);
tree[p].add = 0;
update(p);
return;
}
}
void change(int l, int r, int p, int x)
{
if(l <= tree[p].l && r >= tree[p].r)
{
tree[p].add += x;
tree[p].sum += (SZ(p)*x);
return;
}
spread(p);
int mid = (tree[p].l+tree[p].r)>>1;
if(l <= mid) change(l,r,L(p),x);
if(r > mid) change(l,r,R(p),x);
update(p);
return;
}
LL ask(int l, int r, int p)
{
if(l <= tree[p].l && r >= tree[p].r)
return tree[p].sum;
spread(p);
LL ans = 0;
int mid = (tree[p].l+tree[p].r)>>1;
if(l <= mid) ans += ask(l,r,L(p));
if(r > mid) ans += ask(l,r,R(p));
update(p);
return ans;
}
int main()
{
int n;
cin >> n;
for(int i = 1; i <= n; ++ i) scanf("%d", &xl[i]);
build(1,n,1);
int Q;
cin >> Q;
while(Q--)
{
int t, a, b, x;
scanf("%d", &t);
if(t == 1)
{
scanf("%d%d%d", &a, &b, &x);
change(a,b,1,x);
}
else{
scanf("%d%d", &a, &b);
printf("%lld\n", ask(a,b,1));
}
}
return 0;
}
高精度
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAXN (100000)
struct Big{
int a[MAXN];
int len;
void print()
{
while(!a[this->len] && this->len) --this->len;
for(int i = this->len; i >= 1; -- i)
printf("%d", this->a[i]);
if(!this->len) puts("0");
else puts("");
}
};
Big operator + (Big A, Big B)
{
A.len = max(A.len, B.len)+1;
for(int i = 1; i <= A.len; ++ i)
{
A.a[i] += B.a[i];
A.a[i+1] += (A.a[i]/10);
A.a[i] %= 10;
}
return A;
}
bool operator < (Big A, Big B)
{
if(A.len != B.len) return A.len < B.len;
for(int i = A.len; i >= 1; -- i)
return A.a[i] < B.a[i];
return true;
}
Big t;
void swap(Big &A, Big &B) {t = A; A = B; B = t;}
Big operator - (Big A, Big B)
{
if(A < B) swap(A, B), putchar('-');
for(int i = 1; i <= A.len; ++ i)
{
A.a[i] -= B.a[i];
if(A.a[i] < 0)
{
A.a[i] += 10;
-- A.a[i+1];
}
}
return A;
}
Big T;
Big operator * (Big A, Big B)
{
T.len = A.len+B.len;
for(int i = 1; i <= A.len; ++ i)
for(int j = 1; j <= B.len; ++ j)
{
T.a[i+j-1] += (A.a[i]*B.a[j]);
T.a[i+j] += (T.a[i+j-1]/10);
T.a[i+j-1] %= 10;
}
return T;
}
char s[MAXN];
void read(Big &A)
{
scanf("%s", s+1);
A.len = strlen(s+1);
for(int i = 1; i <= A.len; ++ i)
A.a[A.len-i+1] = (int)(s[i]-'0');
}
Big A, B, C;
int main()
{
read(A); read(B);
C = A+B;
// C = A-B;
// C = A*B;
C.print();
return 0;
}
BLESS ALL.
(圖侵刪, 圖雜)