目录
- 基础算法
- 二分
- 模拟(未补)
- 高精(未学习)
- 搜索(未补)
- 排序
- 图论
- 树的直径
- 树的重心
- 最短路算法
- Spfa
- Dijkstra
- Floyd
- 最小生成树
- kruskal
- 数论
- 线性筛
- 线性筛素数
- 线性筛phi
- 线性筛莫比乌斯函数
- gcd(最大公因数)
- lcm(最小公倍数)
- 快速幂
- 扩展欧几里得算法
- 逆元
- 矩阵快速幂
- 线性筛
- 数据结构
- ST表
- 并查集
未完成先看吧.大概9.1号完成.
然而现在都8102年了...
基础算法
二分
求最小值最大.
跳石头
#include
#include
using namespace std;
const int maxN = 50000 + 7;
int a[maxN],n,m;
int L;
inline int read() {
register int x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
return x * f;
}
bool calc(int k) {
int num = 0,path = 0;
for(int i = 1;i <= n;++ i) {
if(a[i] - a[path] < k) {
num ++;
}else path = i;
}
return num <= m;
}
int main() {
L = read();n = read();m = read();
for(int i = 1;i <= n;++ i) a[i] = read();
n ++;
a[n] = L;
int l = 0,r = L,ans;
while(l <= r) {
int mid = (l + r) >> 1;
if(calc(mid)) {
ans = mid;
l = mid + 1;
}
else r = mid - 1;
}
printf("%d",ans);
return 0;
}
模拟(未补)
高精(未学习)
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct bignum
{
int n;
int a[500];
bignum()
{
n = 0;
memset(a, 0, sizeof(a));
}
bignum(string s)
{
n = s.size();
memset(a, 0, sizeof(a));
for (int i = 0; i < n; i++)
a[i] = s[n - 1 -i] -'0';
}
bignum(int s)
{
memset(a, 0, sizeof(a));
n = 0;
while (s > 0)
{
a[n] = s % 10;
s /= 10;
n++;
}
}
void work()
{
for (int i = 0; i < n; i++)
{
if (a[i] < 0)
{
int tmp = (-a[i] - 1) / 10 + 1;
a[i] += 10 * tmp;
a[i + 1] -= tmp;
}
if (a[i] >= 10)
{
int tmp = a[i] / 10;
a[i] -= 10* tmp;
a[i + 1] += tmp;
if (i == n - 1 && a[i + 1] > 0) n++;
}
}
while (n > 0 && a[n - 1] == 0) n--;
}
void print()
{
for (int i = n - 1; i >= 0; i--)
cout << a[i];
cout << endl;
}
};
bignum operator + (const bignum &a, const bignum &b)
{
bignum c;
c.n = max(a.n, b.n);
for (int i = 0; i < c.n; i++)
c.a[i] = a.a[i] + b.a[i];
c.work();
return c;
}
bignum operator - (const bignum &a, const bignum &b)
{
bignum c;
c.n = max(a.n, b.n);
for (int i = 0; i < c.n; i++)
c.a[i] = a.a[i] - b.a[i];
c.work();
return c;
}
bignum operator * (const bignum &a, const bignum &b)
{
bignum c;
c.n = a.n + b.n - 1;
for (int i = 0; i < a.n; i++)
for (int j = 0; j < b.n; j++)
c.a[i + j] += a.a[i] * b.a[j];
c.work();
return c;
}
int main()
{
string s;
cin >> s;
int x;
cin >> x;
bignum a(s);
bignum b(x);
(a + b).print();
(a - b).print();
(a * b).print();
return 0;
}
搜索(未补)
排序
merge_sort(归并排序)
#include
#include
const int maxN = 100000 + 7;
int z[maxN],a[maxN];
inline int read() {
int x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
return x * f;
}
void merge(int l,int r) {
if(l == r) return;
int mid = l + r >> 1;
merge(l,mid);
merge(mid + 1,r);
int z1 = l,z2 = mid + 1;
for(int i = l;i <= r;++ i) {
if(z1 <= mid)
if(z2 <= r)
if(a[z1] >= a[z2]) z[i] = a[z2 ++];
else z[i] = a[z1 ++];
else z[i] = a[z1 ++];
else z[i] = a[z2 ++];
}
for(int i = l;i <= r;++ i)
a[i] = z[i];
}
int main() {
int n = read();
for(int i = 1;i <= n;++ i)
a[i] = read();
merge(1,n);
for(int i = 1;i <= n;++ i)
printf("%d ",a[i]);
return 0;
}
图论
树的直径
POJ2631
#include
#include
#include
#include
const int maxN = 10000 + 7;
using namespace std;
int ans,id,n = 1;
int Rode[maxN];
struct Node{
int v,w;
};
vectorQ[maxN];
void dfs1(int now,int fa) {
for(int i = 0;i < Q[now].size();++ i) {
int v = Q[now][i].v,w = Q[now][i].w;
if(v == fa) continue;
Rode[v] = Rode[now] + w;
dfs1(v,now);
}
return;
}
int max(int a,int b) {
return a > b ? a : b ;
}
int main() {
#ifdef WIN32
freopen("a.txt","r",stdin);
#endif
int u,v,w;
while(scanf("%d%d%d",&u,&v,&w) == 3) {
Q[u].push_back((Node) {v,w});
Q[v].push_back((Node) {u,w});
n ++;
}
dfs1(1,-1);
for(int i = 1;i <= n;++ i) {
if(ans < Rode[i]) {
ans = Rode[i];
id = i;
}
}
memset(Rode,0,sizeof(Rode));
dfs1(id,-1);
ans = 0;
for(int i = 1;i <= n;++ i)
ans = max(ans,Rode[i]);
printf("%d",ans);
return 0;
}
树的重心
POJ1655
#include
#include
#include
const int maxN = 20000 + 7;
using namespace std;
vector g[maxN];
int n;
int ans,id;
int max(int a,int b) {return a > b ? a : b;}
int min(int a,int b) {return a > b ? b : a;}
int dfs(int now,int fa) {
int son = 1,maxson = 0,kkk;
for(int i = 0;i < g[now].size();++ i) {
int v = g[now][i];
if(v == fa) continue;
int Q = dfs(v,now);
son += Q;
maxson = max(maxson,Q);
}
kkk = max(maxson,n - son);
if(kkk < ans) {
ans = kkk;
id = now;
}
return son;
}
int main() {
int T;
scanf("%d",&T);
while(T --) {
scanf("%d",&n);
for(int i = 1;i <= n;++ i)
g[i].clear();
for(int i = 1,u,v;i < n;++ i) {
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
ans = 0x7fffffff;
dfs(1,-1);
printf("%d %d\n",id,ans);
}
return 0;
}
最短路算法
题目
单源最短路径(弱化版)
Spfa
#include
#include
#include
#include
const int maxN = 100000 + 7;
const int maxM = 200000 + 7;
const int inf = 2147483647;
using namespace std;
int dis[maxN];
bool vis[maxN];
int max(int a,int b) {return a > b ? a : b;}
int min(int a,int b) {return a > b ? b : a;}
struct Node{
int v,w,nex;
}Map[maxM];
int head[maxN],num;
void add_Node(int u,int v,int w) {
Map[++ num].v = v;
Map[num].w = w;
Map[num].nex = head[u];
head[u] = num;
return;
}
void spfa(int now) {
queueq;
q.push(now);
vis[now] = true;
dis[now] = 0;
while(!q.empty()) {
int u = q.front();q.pop();
vis[u] = 0;
for(int i = head[u];i != -1;i = Map[i].nex) {
int v = Map[i].v;
if(dis[v] > dis[u] + Map[i].w) {
dis[v] = dis[u] + Map[i].w;
if( !vis[v] ) {
vis[v] = true;
q.push(v);
}
}
}
}
return ;
}
int main() {
memset(dis,0x3f,sizeof(dis));
memset(head,-1,sizeof(head));
int n,m,s;
scanf("%d%d%d",&n,&m,&s);
for(int i = 1,u,v,w;i <= m;++ i) {
scanf("%d%d%d",&u,&v,&w);
add_Node(u,v,w);
}
spfa(s);
for(int i = 1;i <= n;++ i)
printf("%d ",dis[i] == 0x3f3f3f3f ? inf : dis[i]);
return 0;
}
Dijkstra
#include
#include
#include
using namespace std;
const int inf = 0x7fffffff;
const int maxN = 100000 + 7;
const int maxM = 200000 + 7;
struct Node{
int x,y;
inline bool operator < (const Node &a) const {
return y > a.y;
}
};
priority_queue q;
struct qode{
int v,nex,w;
}Map[maxM];
int s,dis[maxN],n,m,num,head[maxN];
void add_Node(int u,int v,int w) {
Map[++ num].v = v;
Map[num].w = w;
Map[num].nex = head[u];
head[u] = num;
}
void dij() {
for(int i = 1;i <= n;++ i) dis[i] = inf;
q.push((Node){s,0});
dis[s] = 0;
while(!q.empty()) {
Node x = q.top();q.pop();
if(x.y != dis[x.x]) continue;
for(int i = head[x.x];i;i = Map[i].nex) {
int v = Map[i].v;
if(dis[v] > dis[x.x] + Map[i].w) {
dis[v] = dis[x.x] + Map[i].w;
q.push((Node){v,dis[v]});
}
}
}
for(int i = 1;i <= n;++ i) {
printf("%d ",dis[i]);
}
}
int main() {
scanf("%d%d%d",&n,&m,&s);
for(int i = 1,u,v,w;i <= m;++ i) {
scanf("%d%d%d",&u,&v,&w);
add_Node(u,v,w);
}
dij();
return 0;
}
Floyd
#include
#include
#include
#include
using namespace std;
int a[101][101];
int main() {
int n,m,s;
scanf("%d%d%d",&n,&m,&s);
memset(a,0x3f,sizeof(a));
for(int i = 1,u,v,w;i <= m;++ i) {
scanf("%d%d%d",&u,&v,&w);
a[u][v]=min(a[u][v],w);
}
for(int k = 1;k <= n;++ k)
for(int i = 1;i <= n;++ i)
for(int j = 1;j <= n;++ j)
a[i][j] = min(a[i][j],a[i][k] + a[k][j]);
a[s][s] = 0;
for(int i = 1;i <= n;++ i) {
printf("%d ",a[s][i] == 0x3f3f3f3f ? 2147483647 : a[s][i]);
}
}
最小生成树
kruskal
#include
#include
#include
using namespace std;
const int maxN = 5000 + 7;
const int maxM = 200000 + 7;
inline int read() {
int x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
return x * f;
}
struct Node {
int u,v,w;
}Q[maxM];
int fa[maxN];
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void un(int a,int b) {
int faa = find(a),fab = find(b);
fa[faa] = fab;
return;
}
bool cmp(Node a,Node b) {
return a.w < b.w;
}
int num = 0;
void add_Node(int u,int v,int w) {
Q[++ num].u = u;
Q[num].v = v;
Q[num].w = w;
}
int main() {
int n,m;
n = read();m = read();
for(int i = 1;i <= n;++ i) fa[i] = i;
for(int i = 1,u,v,w;i <= m;++ i) {
u = read();v = read();w = read();
add_Node(u,v,w);
}
sort(Q + 1,Q + m + 1,cmp);
int sum = 0,k = 0;
for(int i = 1;i <= m;++ i) {
int fau = find(Q[i].u),fav = find( Q[i].v);
if(fau != fav) {
k ++ ;
sum += Q[i].w;
un(fau,fav);
if(k == n - 1) break;
}
}
if(k == n - 1) printf("%d",sum);
else printf("orz");
}
数论
线性筛
线性筛素数
void init1(int n) {
vis[1] = 1;
for(int i = 2;i <= n;++ i) {
if(!vis[i]) prime[++ num] = i;
for(int j = 1;prime[j] * i <= n;++ j) {
vis[i * prime[j]] = true;
if(i % prime[j] == 0) break;
}
}
}
线性筛phi
int phi[maxN];
void init2(int n) {
vis[1] = 1;
phi[1] = 1;
for(int i = 2;i <= n;++ i) {
if( !vis[i] ) {
prime[++ num] = i;
phi[i] = i - 1;
}
for(int j = 1;j <= num && prime[j] * i <= n;++ j) {
vis[i * prime[j]] = true;
if(i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] *( prime[j] - 1);
}
}
}
线性筛莫比乌斯函数
int mu[maxN];
void init3(int n) {
vis[1] = 1;
mu[1] = 1;
for(int i = 2;i <= n;++ i) {
if(!vis[i]) {
prime[++ num] = i;
mu[i] = -1;
}
for(int j = 1;j <= num && prime[j] * i <= n;++ j) {
vis[i * prime[j]] = true;
if(i % prime[j] == 0) {
mu[i * prime[j]] = 0;
break;
}
mu[i * prime[j]] = -mu[i];
}
}
return;
}
gcd(最大公因数)
int gcd(int a,int b) {
while(b ^= a ^= b ^= a %= b);
return a;
}
lcm(最小公倍数)
int lcm(int a,int b) {
return a / gcd(a,b) * b;
}
快速幂
int fast_pow(int a,int b,int k) {
int ans = 1;
for(int now = a;b;b >>= 1,now = now * now) {
now %= k;
if(b & 1) ans *= now;
ans %= k;
}
return ans % k;
}
扩展欧几里得算法
void exgcd(int a,int b,int &x,int &y) {
if( !b ) {
x = 1;
y = 0;
return;
}
exgcd(b,a % b,x,y);
int tmp = x;
x = y;
y = tmp - (a / b) * y;
return;
}
逆元
nt inv(int n,int p) {
for(int i = 1,x,y;i <= n;++ i) {
exgcd(i,p,x,y);
printf("%d\n",(x % p + p) % p);
}
} //a * x ≡ q (mod p)
矩阵快速幂
ll n,m,k;
struct Marix{
ll s[107][107];
void clear() {
memset(s,0,sizeof(s));
return;
}
}ans,now,a;
Marix work(Marix a,Marix b) {
Marix c;
c.clear();
for(ll i = 1;i <= n;++ i)
for(ll j = 1;j <= n;++ j)
for(ll k = 1;k <= n;++ k)
c.s[i][j] = ( c.s[i][j] % mod+ ( a.s[i][k] * b.s[k][j] ) % mod ) % mod;
return c;
}
void fast_pow() {
ans.clear();
for(ll i = 1;i <= n;++ i) {
ans.s[i][i] = 1;
}
for(now = a;k;k >>= 1,now = work(now,now)) {
if(k & 1) ans = work(ans,now);
}
for(ll i = 1;i <= n;++ i) {
for(ll j = 1;j <= n;++ j) {
printf("%lld ",ans.s[i][j]);
}
puts("");
}
}
void Marix_fast_power() {
scanf("%lld%lld",&n,&k);
for(int i = 1;i <= n;++ i) {
for(int j = 1;j <= n;++ j) {
scanf("%lld",&a.s[i][j]);
}
}
fast_pow();
return ;
}
数据结构
ST表
#include
#include
#define max(a,b) a > b ? a : b
#define min(a,b) a > b ? b : a
const int maxN = 1e5 + 7;
using namespace std;
int f[maxN][21];
int a[maxN];
int bin[maxN];
int n,m;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
void build_st() {
for(int i = 1;(1 << i) <= n;++ i)
bin[(1 << i)] = i;
for(int i = 3;i <= n;++ i)
if(!bin[i]) bin[i] = bin[i - 1];
for(int i = 1;i <= n;++ i)
f[i][0] = a[i];
for(int j = 1;(1 << j) <= n;++ j) {
for(int i = 1;i + (1 << j) - 1 <= n;++ i) {
f[i][j] = max(f[i + (1 << (j - 1))][j - 1],f[i][j - 1]);
}
}
}
int query(int l,int r) {
int x = bin[r - l + 1];
return max(f[l][x],f[r - (1 << x) + 1][x]);
}
int main() {
n = read();m = read();
for(int i = 1;i <= n;++ i)
a[i] = read();
build_st();
int l,r;
while(m --) {
l = read();r = read();
printf("%d\n",query(l,r));
}
return 0;
}
并查集
#include
#include
using namespace std;
const int maxN = 10000 + 7;
int fa[maxN];
inline int read() {
int x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
return x * f;
}
int find(int x) {
return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}
void unit(int u,int v) {
int fau = find(u),fav = find(v);
fa[fau] = fav;
return;
}
int main() {
int n,m;
n = read();m = read();
for(int i = 1;i <= 10000;++ i)
fa[i] = i;
int opt,u,v;
while(m -- ) {
opt = read();u = read();v = read();
if(opt & 1) unit(u,v);
else {
int fau = find(u),fav = find(v);
if(fau == fav) printf("Y\n");
else printf("N\n");
}
}
}