算法模板
算法模板
1.排序
(1)快速排序(No STL)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,a[100010];
void dfs(int l,int r)
{
if(l >= r)
return ;
int pos = (l + r) >> 1;
int x = a[pos];
int i = l,j = r;
while(i <= j)
{
while(a[i] < x)
i++;
while(a[j] > x)
j--;
if(i <= j)
swap(a[i],a[j]),i++,j--;
}
dfs(l,j);
dfs(i,r);
}
signed main()
{
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
dfs(1,n);
for(int i = 1; i <= n; i++)
cout << a[i] << " ";
cout << "\n";
return 0;
}
(2)合并排序
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,a[500010],b[500010],ans = 0;
void merge_sort(int l,int r)
{
if(l >= r)
return ;
int now = l - 1;
int mid = (l + r) >> 1;
merge_sort(l,mid);
merge_sort(mid + 1,r);
int i = l,j = mid + 1;
while(i <= mid && j <= r)
{
if(a[i] <= a[j])
b[++now] = a[i],i++;
else
b[++now] = a[j],j++,ans += mid - i + 1; // ans表示逆序对数量
}
while(i <= mid)
b[++now] = a[i],i++;
while(j <= r)
b[++now] = a[j],j++;
for(int i = l; i <= r; i++)
a[i] = b[i];
}
signed main()
{
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
merge_sort(1,n);
//输出....
return 0;
}
2.二分
(1)整数三分
int l = ...,r = ...,ans = ...;
while(r - l >= 3)
{
int m1 = l + (r - l) / 3;
int m2 = r - (r - l) / 3;
if(f(m1) > f(m2))
ans = l,l = m1 + 1;
else
r = m2 - 1;
}
while(l <= r)
{
if(f(l) < f(ans))
ans = l;
l++;
}
(2)小数三分
double l = ...,r = ...;
while(l + eps < r)
{
double m1 = (l + l + r) / 3.0;
double m2 = (l + r + r) / 3.0;
if(check(m1) < check(m2))
r = m2;
else
l = m1;
}
然后答案是check(l)或者l
(其中的eps根据题目中要求的精度来定)
(3)二分
int l = ...,r = ...,ans = 0;
while(l <= r)
{
int mid = (l + r) / 2;
if(check(mid))
ans = mid,r = mid - 1;
else
l = mid + 1;
}
3.表达式
(1)中缀表达式转后缀表达式并计算及输出过程
#include <bits/stdc++.h>
using namespace std;
#define int long long
string st;
int top = 0,lf[210],rt[210],num[210],cnt = 0,pd[210],tot = 0,d[210],sk[210];
char op[210];
void solve(int x,int l,int r)
{
if(l == r)
{
num[x] = st[l] - '0';
return ;
}
int p = -1,q = -1,t = -1;
for(int i = l; i <= r; i++)
{
if(st[i] == '(')
i = pd[i];
else if(st[i] == '+' || st[i] == '-')
p = i;
else if(st[i] == '*' || st[i] == '/')
q = i;
else if(st[i] == '^' && t == -1)
t = i;
}
if(p == -1)
p = q;
if(p == -1)
p = t;
if(p == -1)
solve(x,l + 1,r - 1);
else
{
op[x] = st[p];
lf[x] = ++cnt;
solve(lf[x],l,p - 1);
rt[x] = ++cnt;
solve(rt[x],p + 1,r);
}
}
void dfs(int x)
{
if(lf[x])
dfs(lf[x]);
if(rt[x])
dfs(rt[x]);
d[++tot] = x;
}
void out(int y)
{
for(int i = 1; i <= top; i++)
cout << sk[i] << " ";
for(int i = y; i <= tot; i++)
{
if(lf[d[i]] == 0)
cout << num[d[i]] << " ";
else
cout << op[d[i]] << " ";
}
cout << "\n";
}
int qp(int x,int y)
{
int sum = 1;
while(y > 0)
{
if(y & 1)
sum *= x;
x *= x;
y >>= 1;
}
return sum;
}
signed main()
{
cin >> st;
for(int i = 0; i < st.length(); i++)
{
if(st[i] == '(')
sk[++top] = i;
else if(st[i] == ')')
pd[sk[top]] = i,top--;
}
cnt = 1;
solve(1,0,st.length() - 1);
dfs(1);
out(1);
for(int i = 1; i <= tot; i++)
{
if(lf[d[i]] == 0)
sk[++top] = num[d[i]];
else
{
int y = sk[top--],x = sk[top--],z;
switch(op[d[i]])
{
case '+' : z = x + y; break;
case '-' : z = x - y; break;
case '*' : z = x * y; break;
case '/' : z = x / y; break;
case '^' : z = qp(x,y); break;
}
sk[++top] = z;
out(i + 1);
}
}
return 0;
}
4.RMQ与ST表
(1)普通模板,min和max可改
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m,p[100010][20];
inline int read()
{
int x = 0,f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = x * 10 + ch - 48;
ch = getchar();
}
return x * f;
}
signed main()
{
n = read(),m = read();
for(int i = 1; i <= n; i++)
p[i][0] = read();
for(int j = 1; (1 << j) <= n; j++)
{
for(int i = 1; i + (1 << j - 1) <= n; i++)
p[i][j] = max(p[i][j - 1],p[i + (1 << j - 1)][j - 1]);
}
while(m--)
{
int l,r;
l = read(),r = read();
int t = log2(r - l + 1);
cout << max(p[l][t],p[r - (1 << t) + 1][t]) << "\n";
}
return 0;
}
(2)log2函数的数组预处理
for(int i = 2; i <= 最大范围; i++)
lg[i] = lg[i >> 1] + 1;
使用:lg[数字]
(3)在末尾添加数字后更新ST表
p[++n][0] = x;
for(int j = 1; n - (1 << j) + 1 > 0; j++)
p[n - (1 << j) + 1][j] = max(p[n - (1 << j) + 1][j - 1],p[n - (1 << j - 1) + 1][j - 1]);
5.并查集
(1)普通模板
#include <bits/stdc++.h>
using namespace std;
#define int long long
int f[10010];
int find(int x)
{
if(f[x] == x)
return x;
return f[x] = find(f[x]);
}
void merge(int x,int y)
{
int f1 = find(x),f2 = find(y);
f[f1] = f2;
}
signed main()
{
int n,m;
cin >> n >> m;
iota(f + 1,f + n + 1,1);
for(int i = 1; i <= m; i++)
{
int z,x,y;
cin >> z >> x >> y;
if(z == 1)
merge(x,y);
else
{
int f1 = find(x),f2 = find(y);
if(f1 == f2)
cout << "Y" << "\n";
else
cout << "N" << "\n";
}
}
return 0;
}
6.最短路
(1)Floyd多源最短路
#include <bits/stdc++.h>
using namespace std;
#define int long long
int dis[210][210];
signed main()
{
int n,m;
cin >> n >> m;
memset(dis,0x3f,sizeof(dis));
for(int i = 1; i <= m; i++)
{
int a,b,c;
cin >> a >> b >> c;
dis[a][b] = min(dis[a][b],c);
}
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]);
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(dis[i][j] < 0x3f3f3f3f)
cout << dis[i][j] << " ";
else
cout << -1 << " ";
}
cout << "\n";
}
return 0;
}
(2)Dijkstra
#include <bits/stdc++.h>
using namespace std;
#define int long long
int s,dis[100010];
bool vis[100010];
vector<int> v[100010],d[100010];
typedef pair<int,int> P;
void dijkstra()
{
memset(dis,0x3f,sizeof(dis));
dis[s] = 0;
priority_queue<P,vector<P>,greater<P> > q;
q.push(make_pair(0,s));
while(!q.empty())
{
P tmp = q.top();
q.pop();
if(vis[tmp.second])
continue;
vis[tmp.second] = true;
for(int i = 0; i < v[tmp.second].size(); i++)
{
int to = v[tmp.second][i];
if(dis[to] > dis[tmp.second] + d[tmp.second][i])
{
dis[to] = dis[tmp.second] + d[tmp.second][i];
q.push(make_pair(dis[to],to));
}
}
}
}
signed main()
{
int n,m;
cin >> n >> m >> s;
for(int i = 1; i <= m; i++)
{
int a,b,c;
cin >> a >> b >> c;
v[a].push_back(b);
d[a].push_back(c);
}
dijkstra();
for(int i = 1; i <= n; i++)
{
if(dis[i] < 0x3f3f3f3f)
cout << dis[i] << " ";
else
cout << 2147483647 << " ";
}
cout << "\n";
return 0;
}
(3)Spfa
#include <bits/stdc++.h>
using namespace std;
#define int long long
int s,dis[10010];
bool vis[10010];
vector<int> v[10010],d[10010];
void spfa()
{
memset(dis,0x3f,sizeof(dis));
dis[s] = 0;
vis[s] = true;
queue<int> q;
q.push(s);
while(!q.empty())
{
int now = q.front();
q.pop();
vis[now] = false;
for(int i = 0; i < v[now].size(); i++)
{
if(dis[v[now][i]] > dis[now] + d[now][i])
{
dis[v[now][i]] = dis[now] + d[now][i];
if(!vis[v[now][i]])
{
vis[v[now][i]] = true;
q.push(v[now][i]);
}
}
}
}
}
signed main()
{
int n,m;
cin >> n >> m >> s;
for(int i = 1; i <= m; i++)
{
int a,b,c;
cin >> a >> b >> c;
v[a].push_back(b);
d[a].push_back(c);
}
spfa();
for(int i = 1; i <= n; i++)
{
if(dis[i] < 0x3f3f3f3f)
cout << dis[i] << " ";
else
cout << 2147483647 << " ";
}
cout << "\n";
return 0;
}
(4)Spfa判负环
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m,dis[10010],cnt[10010],cntt = -1,head[10010];
bool vis[10010];
queue<int> q;
struct Node
{
int to,w,nex;
}e[10010];
void add(int u,int v,int w)
{
e[++cntt].to = v;
e[cntt].w = w;
e[cntt].nex = head[u];
head[u] = cntt;
}
void spfa()
{
fill(dis + 1,dis + n + 1,0x3f3f3f3f);
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(vis));
while(!q.empty())
q.pop();
dis[1] = 0;
vis[1] = true;
q.push(1);
while(!q.empty())
{
int tmp = q.front();
q.pop();
vis[tmp] = false;
for(int i = head[tmp]; i != -1; i = e[i].nex)
{
int v = e[i].to;
int w = e[i].w;
if(dis[tmp] + w < dis[v])
{
dis[v] = dis[tmp] + w;
cnt[v] = cnt[tmp] + 1;
if(cnt[v] >= n)
{
cout << "YES" << "\n";
return ;
}
if(!vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
cout << "NO" << "\n";
}
signed main()
{
int t;
cin >> t;
while(t--)
{
cntt = -1;
memset(head,-1,sizeof(head));
cin >> n >> m;
for(int i = 1; i <= m; i++)
{
int u,v,w;
cin >> u >> v >> w;
add(u,v,w);
if(w >= 0)
add(v,u,w);
}
spfa();
}
return 0;
}
(5)查分约束
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m,head[1000010],cnt = 0,cntt[1000010],dis[1000010];
bool vis[1000010];
struct Node
{
int to,nex,w;
}e[1000010];
void add(int x,int y,int z)
{
cnt++;
e[cnt].to = y;
e[cnt].nex = head[x];
e[cnt].w = z;
head[x] = cnt;
}
void spfa()
{
fill(dis + 1,dis + n + 2,0x3f3f3f3f);
memset(cntt,0,sizeof(cntt));
memset(vis,0,sizeof(vis));
queue<int> q;
dis[n + 1] = 0;
vis[n + 1] = true;
q.push(n + 1);
while(!q.empty())
{
int tmp = q.front();
q.pop();
vis[tmp] = false;
for(int i = head[tmp]; i; i = e[i].nex)
{
int v = e[i].to;
int w = e[i].w;
if(dis[tmp] + w < dis[v])
{
dis[v] = dis[tmp] + w;
cntt[v] = cntt[tmp] + 1;
if(cntt[v] >= n)
{
cout << "NO SOLUTION" << "\n";
exit(0);
}
if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
}
signed main()
{
cin >> n >> m;
for(int i = 1; i <= m; i++)
{
int ii,j,b;
cin >> ii >> j >> b;
add(j,ii,b);
}
for(int i = 1; i <= n; i++)
add(n + 1,i,0);
spfa();
int mind = 0x3f3f3f3f;
for(int i = 1; i <= n; i++)
mind = min(mind,dis[i]);
for(int i = 1; i <= n; i++)
cout << dis[i] - mind << "\n";
return 0;
}
记住就是add(a,b,c)时表示a - b >= -c
7.最小生成树
(1)Kruskal
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m,tot = 0,f[5010],ans = 0,cnt = 0;
struct Node
{
int u,v,w;
}e[400010];
bool cmp(Node x,Node y)
{
return x.w < y.w;
}
int find(int x)
{
if(f[x] == x)
return x;
return f[x] = find(f[x]);
}
void merge(int x,int y)
{
int fx = find(x),fy = find(y);
if(fx == fy)
return ;
f[fx] = fy;
}
bool with(int x,int y)
{
if(find(x) == find(y))
return true;
return false;
}
void kruskal()
{
for(int i = 1; i <= m; i++)
{
int u = e[i].u,v = e[i].v;
if(with(u,v))
continue;
merge(u,v);
ans += e[i].w;
if(++cnt == n - 1)
break;
}
}
signed main()
{
cin >> n >> m;
iota(f + 1,f + n + 1,1);
for(int i = 1; i <= m; i++)
cin >> e[i].u >> e[i].v >> e[i].w;
sort(e + 1,e + m + 1,cmp);
kruskal();
if(cnt == n - 1)
cout << ans << "\n";
else
cout << "orz" << "\n";
return 0;
}
(2)Prim
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,c,x[5010],y[5010],dis[5010];
bool vis[5010];
int cal(int a,int b)
{
return (x[a] - x[b]) * (x[a] - x[b]) + (y[a] - y[b]) * (y[a] - y[b]);
}
void prim()
{
memset(dis,0x3f,sizeof(dis));
dis[1] = 0;
for(int i = 1; i <= n; i++)
{
int to = 0;
for(int i = 1; i <= n; i++)
{
if(!vis[i] && dis[i] < dis[to])
to = i;
}
if(to == 0 || dis[to] == 0x3f3f3f3f)
{
cout << -1 << "\n";
exit(0);
}
vis[to] = true;
for(int j = 1; j <= n; j++)
{
if(!vis[j] && j != to)
{
if(cal(j,to) >= c)
dis[j] = min(dis[j],cal(j,to));
}
}
}
}
signed main()
{
cin >> n >> c;
for(int i = 1; i <= n; i++)
cin >> x[i] >> y[i];
prim();
int ans = 0;
for(int i = 1; i <= n; i++)
{
if(dis[i] == 0x3f3f3f3f)
{
cout << -1 << "\n";
goto tag;
}
ans += dis[i];
}
cout << ans << "\n";
tag:;
return 0;
}
8.拓扑排序
(1)普通模板
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,head[30010],in[30010],a[30010],cnt = 0,tot = 0;
struct Node
{
int nex,to;
}e[1000010];
void add(int x,int y)
{
cnt++;
e[cnt].nex = head[x];
e[cnt].to = y;
head[x] = cnt;
}
void toposort()
{
priority_queue<int,vector<int>,greater<int> > q;
for(int i = 1; i <= n; i++)
{
if(in[i] == 0)
q.push(i);
}
while(!q.empty())
{
int u = q.top();
q.pop();
a[++tot] = u;
for(int i = head[u]; i; i = e[i].nex)
{
int v = e[i].to;
in[v]--;
if(in[v] == 0)
q.push(v);
}
}
}
signed main()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
int m;
cin >> m;
for(int j = 1; j <= m; j++)
{
int y;
cin >> y;
add(i,y);
in[y]++;
}
}
toposort();
if(tot != n)
cout << "no solution" << "\n";
else
{
cout << n << "\n";
for(int i = 1; i <= n; i++)
cout << a[i] << " ";
cout << "\n";
}
return 0;
}
9.强联通分量
(1)Tarjan
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int dfn[10010],low[10010],co[10010],col = 0,tot = 0,t[10010],ans = 0,head[10010],cnt = 0;
bool ins[10010];
stack<int> st;
struct Node
{
int to,nex;
}e[50010];
void add(int x,int y)
{
cnt++;
e[cnt].to = y;
e[cnt].nex = head[x];
head[x] = cnt;
}
void tarjan(int u)
{
dfn[u] = low[u] = ++tot;
st.push(u);
ins[u] = true;
for(int i = head[u]; i; i = e[i].nex)
{
int v = e[i].to;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u],low[v]);
}
else if(ins[v])
low[u] = min(low[u],low[v]);
}
if(low[u] == dfn[u])
{
int cnt = 0;
col++;
int y;
while(y = st.top())
{
st.pop();
co[y] = col;
cnt++;
ins[y] = false;
if(u == y)
break;
}
if(cnt > 1)
ans++;
}
}
signed main()
{
cin >> n >> m;
for(int i = 1; i <= m; i++)
{
int a,b;
cin >> a >> b;
add(a,b);
}
for(int i = 1; i <= n; i++)
{
if(!dfn[i])
tarjan(i);
}
cout << ans << "\n";
return 0;
}
(2)计算割点数量
#include <bits/stdc++.h>
using namespace std;
#define int long long
vector<int> v[110];
int n,tot = 0,low[110],dfn[110],root = 0,ans = 0;
bool tarjan(int x)
{
dfn[x] = low[x] = ++tot;
bool flag = false;
int child = 0;
for(int i = 0; i < v[x].size(); i++)
{
int y = v[x][i];
if(!dfn[y])
{
tarjan(y);
child++;
low[x] = min(low[x],low[y]);
if(dfn[x] <= low[y])
flag = true;
}
else
low[x] = min(low[x],dfn[y]);
}
if(x == root && child < 2)
flag = false;
if(flag)
ans++;
}
signed main()
{
while(true)
{
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
tot = 0;
ans = 0;
root = 0;
cin >> n;
for(int i = 1; i <= n; i++)
v[i].clear();
if(n == 0)
break;
while(true)
{
int x;
cin >> x;
if(x == 0)
break;
string s;
getline(cin,s);
s = s + ' ';
int i = 0,num = 0;
while(s[i] < '0')
i++;
for(; i < s.length(); i++)
{
if(s[i] >= '0' && s[i] <= '9')
num = num * 10 + (s[i] - '0');
else if(num != 0)
{
v[num].push_back(x);
v[x].push_back(num);
num = 0;
}
}
}
for(int i = 1; i <= n; i++)
{
if(!dfn[i])
root = i,tarjan(i);
}
cout << ans << "\n";
}
return 0;
}
(3)计算桥数量
#include <bits/stdc++.h>
using namespace std;
#define int long long
vector<int> v[30010];
int n,m,tot = 0,ans = 0,low[30010],dfn[30010];
void tarjan(int x,int fa)
{
dfn[x] = low[x] = ++tot;
for(int i = 0; i < v[x].size(); i++)
{
int y = v[x][i];
if(y == fa)
continue;
if(!dfn[y])
{
tarjan(y,x);
low[x] = min(low[x],low[y]);
if(dfn[x] < low[y])
ans++;
}
else
low[x] = min(low[x],dfn[y]);
}
}
signed main()
{
while(true)
{
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
tot = 0;
ans = 0;
cin >> n >> m;
for(int i = 1; i <= n; i++)
v[i].clear();
if(n == 0 && m == 0)
break;
for(int i = 1; i <= m; i++)
{
int a,b;
cin >> a >> b;
v[a].push_back(b);
v[b].push_back(a);
}
tarjan(1,0);
cout << ans << "\n";
}
return 0;
}
(4)找割点
#include <bits/stdc++.h>
using namespace std;
#define int long long
bool cut[200010];
int cnt = 0,head[200010],n,a,b,dfn[200010],low[200010],tot;
struct Node
{
int to,nex;
}e[1000010];
void add(int u,int v)
{
cnt++;
e[cnt].to = v;
e[cnt].nex = head[u];
head[u] = cnt;
}
void tarjan(int u)
{
dfn[u] = low[u] = ++tot;
for(int i = head[u]; i; i = e[i].nex)
{
int v = e[i].to;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u],low[v]);
if(dfn[u] <= low[v] && u != a && dfn[v] <= dfn[b])
cut[u] = 1;
}
else
low[u] = min(low[u],dfn[v]);
}
}
signed main()
{
cin >> n;
int u,v;
while(true)
{
cin >> u >> v;
if(u == 0 && v == 0)
break;
add(u,v);
add(v,u);
}
cin >> a >> b;
tarjan(a);
for(int i = 1; i <= n; i++)
{
if(cut[i])
{
cout << i << "\n";
return 0;
}
}
cout << "No solution" << "\n";
return 0;
}
10.二叉树
(1)给定后序遍历和中序遍历,求先序遍历
#include <bits/stdc++.h>
using namespace std;
#define int long long
void dfs(string zho,string hou)
{
if(zho.length() > 0)
{
char ch = hou[hou.length() - 1];
cout << ch;
int k = zho.find(ch);
dfs(zho.substr(0,k),hou.substr(0,k));
dfs(zho.substr(k + 1),hou.substr(k,zho.length() - k - 1));
}
}
signed main()
{
string a,b;
cin >> a >> b;
dfs(a,b);
cout << "\n";
return 0;
}
11.素数
(1)费马素性检验
(适用于\(2^{32}\)以内,再大就要错)
mt19937 eng(time(0));
int randint(int a, int b) // 生成a到b之间的随机数
{
uniform_int_distribution<int> dis(a, b);
return dis(eng);
}
bool is_prime(int x)
{
if (x < 3) // 因为生成的a∈[2,x-1],要求x≥3,所以特判1,2
return x == 2;
for (int i = 0; i < 12; ++i) // 随机测试12个a
{
int a = randint(2, x - 1);
if (qpow(a, x - 1, x) != 1) // qpow是快速幂
return false;
}
return true;
}
(2)米勒·拉宾素性检验
(适用于\(2^{64}\)以内,再大就要错)
typedef long long ll;
ll qpow(ll a, ll n, ll p) // 快速幂
{
ll ans = 1;
while (n)
{
if (n & 1)
ans = (__int128)ans * a % p; // 注意!中间结果可能溢出,需要使用__int128过渡
a = (__int128)a * a % p;
n >>= 1;
}
return ans;
}
bool is_prime(ll x)
{
if (x < 3) // 特判1,2
return x == 2;
if (x % 2 == 0) // 特判偶数
return false;
ll A[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022}, d = x - 1, r = 0;
while (d % 2 == 0) // 算出d, r
d /= 2, ++r;
// 或:r = __builtin_ctz(d), d >>= r;
for (auto a : A)
{
ll v = qpow(a, d, x); // a^d
// 如果a^d≡0,说明是a是x的倍数;如果a^d≡1或-1,说明这串数接下来一定都是1,不用继续计算
if (v <= 1 || v == x - 1)
continue;
for (int i = 0; i < r; ++i)
{
v = (__int128)v * v % x; // 同样使用__int128过渡
if (v == x - 1 && i != r - 1) // 得到-1,说明接下来都是1,可以退出了
{
v = 1;
break;
}
// 在中途而非开头得到1,却没有经过-1,说明存在其他数字y≠-1满足y^2≡1,则x一定不是奇素数
if (v == 1)
return false;
}
if (v != 1) // 查看是不是以1结尾
return false;
}
return true;
}
12.输入输出
(1)快读(正负通用)
template <typename T> void read(T &t)
{
char c = getchar();
int f = 1;
t = 0;
while(c < '0' || c > '9')
{
if(c == '-')
f = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
{
t = t * 10 + (c - '0');
c = getchar();
}
t *= f;
}
13.高斯消元
(1)简单模板(P3389【模板】高斯消元法&题解)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
double map[111][111];
double ans[111];
double eps=1e-7;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n+1;j++)
scanf("%lf",&map[i][j]);
for(int i=1;i<=n;i++){
int r=i;
for(int j=i+1;j<=n;j++)
if(fabs(map[r][i])<fabs(map[j][i]))
r=j;//find_the_biggest_number_of_the_first_column(at present)
if(fabs(map[r][i])<eps){
printf("No Solution");
return 0;
}
if(i!=r)swap(map[i],map[r]);//对换一行或一列,属于找最大当前系数的其中一步。(这样就可以只处理当前行的系数啦!)
double div=map[i][i];
for(int j=i;j<=n+1;j++)
map[i][j]/=div;
for(int j=i+1;j<=n;j++){
div=map[j][i];
for(int k=i;k<=n+1;k++)
map[j][k]-=map[i][k]*div;
}
}
ans[n]=map[n][n+1];
for(int i=n-1;i>=1;i--){
ans[i]=map[i][n+1];
for(int j=i+1;j<=n;j++)
ans[i]-=(map[i][j]*ans[j]);
}//回带操作
for(int i=1;i<=n;i++)
printf("%.2lf\n",ans[i]);
}

浙公网安备 33010602011771号