1、数组模拟链表
void add(int x,int y,int z)
{
t[++l]=y;
next[l]=last[x];
last[x]=l;
a[l]=z;
}
2、spfa(最短路+数组模拟链表)
void spfa()
{
bz[n]=true;
int l=0;
int r=1;
data[1]=n;
memset(dis,127,sizeof(dis));
dis[n]=0;
while (l!=r)
{
l=l%n+1;
int now=data[l];
int p=last[now];
while (p>0)
{
if (dis[now]+a[p]<dis[t[p]])
{
dis[t[p]]=dis[now]+a[p];
if (!bz[t[p]])
{
bz[t[p]]=true;
r=r%n+1;
data[r]=t[p];
}
}
p=next[p];
}
bz[now]=false;
}
}
3、高精度*低精度
function gjc(x:longint;a:arr):arr;
var
i,j,l:longint;
c:arr;
s:string;
begin
fillchar(c,sizeof(c),0);
str(x,s);
l:=length(s);
while a[a[0]+1]>0 do
a[0]:=a[0]+1;
for i:=1 to a[0] do begin c[i]:=c[i]+a[i]*x;
c[i+1]:=c[i+1]+c[i] div 10;
c[i]:=c[i] mod 10;
end;
if c[l+a[0]]>0 then c[0]:=l+a[0] else c[0]:=l+a[0]-1;
exit(c);
end;
4
高精度加法
var
i,j,k:longint;
c:arr;
begin
fillchar(c,sizeof(c),0);
k:=max(a[0],b[0]);
for i:=1 to k do
begin
c[i]:=c[i]+a[i]+b[i];
c[i+1]:=c[i+1]+c[i] div 10;
c[i]:=c[i] mod 10;
end;
if c[k+1]>0 then c[0]:=k+1
else c[0]:=k;
exit(c);
end;
5 高精度除以低精度
procedure devide(a:hp;b:longint; var c:hp; var d:longint);
{c:=a div b; d:= a mod b}
var i,len:integer;
begin
fillchar(c,sizeof(c),0);
len:=a[0]; d:=0;
for i:=len downto 1 do begin
d:=d*10+a[i];
c[i]:=d div b;
d:=d mod b;
end;
while (len>1) and (c[len]=0) then dec(len);
c[0]:=len;
end;
6、高精度*高精度
var
a,b,c:array[0..1000000] of longint;
i,j,len:longint;
n:ansistring;
begin
assign(input,'bullmath.in');reset(input);
assign(output,'bullmath.out');rewrite(output);
readln(n);
a[0]:=length(n);
for i:=1 to a[0] do
a[i]:=ord(n[a[0]-i+1])-48;
readln(n);
b[0]:=length(n);
for i:=1 to b[0] do
b[i]:=ord(n[b[0]-i+1])-48;
for j:=1 to b[0] do
for i:=1 to a[0] do
begin
c[i+j-1]:=c[i+j-1]+a[i]*b[j];
c[i+j]:=c[i+j]+c[i+j-1] div 10;
c[i+j-1]:=c[i+j-1] mod 10;
end;
if c[a[0]+b[0]]>0 then c[0]:=a[0]+b[0] else c[0]:=a[0]+b[0]-1;
for i:=c[0] downto 1 do write(c[i]);
close(input);
close(output);
end.
7、Tarjan
#include <cstdio>
#include <iostream>
#define N 50001
#define LL long long
#define fo(i,a,b) for (int i=a;i<=b;i++)
using namespace std;
int dfn[N],low[N],zhan[N];
bool v[N];
int t[2*N],next[2*N],last[2*N];
int n,m,l,top=0;
LL ans=0;
void add(int x,int y)
{
t[++l]=y;
next[l]=last[x];
last[x]=l;
}
void tarjan(int x)
{
zhan[++top]=x;
dfn[x]=++l;
low[x]=l;
int k=last[x];
// bz[x]=true;
v[x]=true;
while (k!=0)
{
if (dfn[t[k]]==0)
{
tarjan(t[k]);
if (low[t[k]]<low[x]) low[x]=low[t[k]];
}
else if (v[t[k]] && dfn[t[k]]<low[x]) low[x]=dfn[t[k]];
k=next[k];
}
if (low[x]==dfn[x])
{
LL xdl=0;
while (zhan[top+1]!=x)
{
v[zhan[top]]=false;
top--;
xdl++;
}
ans+=(xdl-1)*xdl/2;
}
}
int main()
{
scanf("%d%d",&n,&m);
int x,y;
fo(i,1,m)
{
scanf("%d%d",&x,&y);
add(x,y);
}
l=0;
fo(i,1,n)
if (not bz[i]) tarjan(i);
printf("%d",ans);
}
8、并查集
int get(int x)
{
if (Dad[x]==0) return x;
else Dad[x]=get(Dad[x]);
return Dad[x];
}
9、最小生成树
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#define fo(i,a,b) for (int i=a;i<=b;i++)
#define N 100000
using namespace std;
struct Samjia
{
int x,y,z;
}b[N];
int a[N],f[N];
bool cmp(Samjia a,Samjia b)
{
return a.z<b.z;
}
int get(int x)
{
if (f[x]==-1) return x;
else f[x]=get(f[x]);
return f[x];
}
int main()
{
int n,t=0;
scanf("%d",&n);
fo(i,1,n)
{
scanf("%d",&a[i]);
b[++t].x=i;
b[t].y=0;
b[t].z=a[i];
}
fo(i,1,n)
fo(j,1,n)
{
int x;
scanf("%d",&x);
if (i<j)
{
b[++t].x=i;
b[t].y=j;
b[t].z=x;
}
}
sort(b+1,b+1+t,cmp);
memset(f,255,sizeof(f));
int k=0,ans=0;
fo(i,1,t)
{
int x=get(b[i].x);
int y=get(b[i].y);
if (x!=y)
{
f[x]=y;
k++;
ans+=b[i].z;
}
if (k==t-1) break;
}
printf("%d",ans);
}
`
10、hash表
const max=10000000;
var
i,j,k,m,n:longint;
h:array[0..max]of longint;
a:array[1..1000]of longint;
function hash(x:longint):longint;
var
t:longint;
begin
t:=x mod max+1;
while (h[t]<>0) and (h[t]<>x) do t:=t mod max+1;
exit(t);
end;
begin
readln(n,m);
for i:=1 to n do
begin
readln(a[i]);
h[hash(a[i])]:=a[i];
end;
for i:=1 to n do
for j:=i to n do
h[hash(a[i]+a[j])]:=a[i]+a[j];
for j:=m downto 1 do
begin
for i:=1 to n do
begin
if (h[hash(abs(j-a[i]))]=j-a[i]) then
begin
writeln(j);
halt;
end;
for k:=i to n do
if (h[hash(abs(j-a[i]-a[k]))]=j-a[i]-a[k]) then
begin
writeln(j);
halt;
end;
end;
end;
writeln(0);
end.
11、树状数组(cj——jzoj 1376求和
var
a,b:array[1..100000]of longint;
i,j,ans,x,y,k,n,m:longint;
ch:char;
function lowbit(x:longint):longint;
begin
exit(x and (-x));
end;
procedure change(x,y:longint);
begin
a[x]:=a[x]+y;
while x<=n do
begin
b[x]:=b[x]+y;
x:=x+lowbit(x);
end;
end;
function sum(x:longint):longint;
var
ans:longint;
begin
ans:=0;
while x>0 do
begin
ans:=ans+b[x];
x:=x-lowbit(x);
end;
exit(ans);
end;
begin
// assign(input,'1376.in');reset(input);
readln(n);
for i:=1 to n do
readln(a[i]);
for i:=1 to n do
begin
k:=lowbit(i);
for j:=i-k+1 to i do
b[i]:=b[i]+a[j];
end;
readln(m);
for i:=1 to m do
begin
readln(ch,x,y);
if ch='C' then change(x,y-a[x])
else writeln(sum(y)-sum(x-1));
end;
end.
12、线段树(jzoj cj——1380 最大值新版)
var
n,i,m,ans,z,x,y,s,p:longint;
a:array[0..100000]of longint;
f,t:array[0..400000]of longint;
function max(a,b:longint):longint;
begin
if a>b then exit(a)
else exit(b);
end;
procedure dg(l,r,wz:longint);
var
i:longint;
begin
if l=r then
begin
f[wz]:=a[l];
t[wz]:=0;
end
else
begin
i:=(l+r) div 2;
dg(l,i,wz*2);
dg(i+1,r,wz*2+1);
f[wz]:=max(f[2*wz],f[2*wz+1]);
t[wz]:=0;
end;
end;
procedure change(l,r,x,y,wz,s:longint);
var
i:longint;
begin
if (l=x)and(r=y) then
begin
f[wz]:=f[wz]+s;
t[wz]:=t[wz]+s;
end
else
begin
p:=wz;
f[wz*2]:=f[wz*2]+t[wz];
f[wz*2+1]:=f[wz*2+1]+t[wz];
t[wz*2]:=t[wz*2]+t[wz];
t[wz*2+1]:=t[wz*2+1]+t[wz];
t[wz]:=0;
i:=(l+r) div 2;
if y<=i then change(l,i,x,y,wz*2,s)
else if x>i then change(i+1,r,x,y,wz*2+1,s);
if (x<=i) and (y>i) then
begin
change(l,i,x,i,wz*2,s);
change(i+1,r,i+1,y,wz*2+1,s);
end;
f[wz]:=max(f[wz*2],f[wz*2+1]);
end;
end;
procedure find(l,r,x,y,wz:longint);
var
i:longint;
begin
if (x=l)and(r=y) then ans:=max(f[wz],ans)
else
begin
f[wz*2]:=f[wz*2]+t[wz];
f[wz*2+1]:=f[wz*2+1]+t[wz];
t[wz*2]:=t[wz*2]+t[wz];
t[wz*2+1]:=t[wz*2+1]+t[wz];
t[wz]:=0;
i:=(l+r) div 2;
if y<=i then find(l,i,x,y,wz*2)
else if x>i then find(i+1,r,x,y,wz*2+1);
if (x<=i) and (y>i) then
begin
find(l,i,x,i,wz*2);
find(i+1,r,i+1,y,wz*2+1);
end;
end;
end;
begin
readln(n);
for i:=1 to n do
readln(a[i]);
dg(1,n,1);
readln(m);
for i:=1 to m do
begin
read(z,x,y);
if z=1 then
begin
read(s);
change(1,n,x,y,1,s);
end
else
begin
ans:=-maxlongint;
find(1,n,x,y,1);
writeln(ans);
end;
end;
end.
LCA(jzoj 3534)
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for (int i=a;i<=b;i++)
#define fd(i,a,b) for (int i=a;i>=b;i--)
#define N 50005
#define INF 21474836
using namespace std;
struct Record
{
int x,y,next,last,val;
}a[N*2],Tree[N*2];
int Dad[N],Dad2[N],Deep[N],b[N],l=0,ll=0,n,m;
bool Bz[N];
void add(int x,int y,int z)
{
a[++l].x=x;
a[l].y=y;
a[l].next=a[x].last;
a[x].last=l;
a[l].val=z;
}
void Add(int x,int y,int z)
{
Tree[++ll].x=x;
Tree[ll].y=y;
Tree[ll].next=Tree[x].last;
Tree[x].last=ll;
Tree[ll].val=z;
}
bool cmp(Record a,Record b)
{
return a.val>b.val;
}
int get(int x)
{
if (!Dad[x]) return x;
else Dad[x]=get(Dad[x]);
return Dad[x];
}
void MST()
{
sort(a+1,a+1+m*2,cmp);
fo(i,1,m*2)
{
int xx=get(a[i].x);
int yy=get(a[i].y);
if (xx!=yy)
{
Dad[xx]=yy;
Add(a[i].x,a[i].y,a[i].val);
Add(a[i].y,a[i].x,a[i].val);
}
}
}
void dg(int x,int y,int z)
{
Bz[x]=true;
Deep[x]=z;
//int k=Tree[x].last;
for(int k=Tree[x].last;k;k=Tree[k].next)
{
int t=Tree[k].y;
if (t==y) continue;
b[t]=Tree[k].val;
Dad2[t]=x;
dg(t,x,z+1);
// k=Tree[k].next;
}
}
int Lca(int x,int y)
{
int Ans=INF,ANS=INF;
if (Deep[x]<Deep[y]) swap(x,y);
while (Deep[x]>Deep[y])
{
Ans=min(Ans,b[x]);
x=Dad2[x];
}
while (x!=y)
{
Ans=min(Ans,b[x]);
ANS=min(ANS,b[y]);
x=Dad2[x];
y=Dad2[y];
}
return min(ANS,Ans);
}
void GetAns()
{
int Q;
scanf("%d",&Q);
while (Q--)
{
int x,y;
scanf("%d%d",&x,&y);
int xx=get(x);
int yy=get(y);
if (xx!=yy)
{
printf("-1\n");
continue;
}
printf("%d\n",Lca(x,y));
}
}
int main()
{
freopen("data.in","r",stdin);
scanf("%d%d",&n,&m);
fo(i,1,m)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
MST();
fo(i,1,n) if (!Bz[i]) dg(i,0,1);
GetAns();
return 0;
}
exgcd(用于解同余方程)例题 jzoj 1158
int Exgcd(int a,int b,int &x,int &y)
{
if (!b)
{
x=1;y=0;
return a;
}
int d=Exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-(a/b)*y;
return d;
}
线性筛法(求素数)
program sushu;
var
a:array[1..1000000] of boolean;
f:array[1..100000] of longint;
i,j,k,n,m,s:longint;
begin
readln(n);
fillchar(a,sizeof(a),0);
s:=0;
for i:=2 to n do
begin
if a[i]=false then
begin
inc(s);
f[s]:=i;
end;
for j:=1 to s do
begin
if i*f[j]>n then break;
a[i*f[j]]:=true;
if i mod f[j]=0 then break;
end;
end;
for i:=1 to s do
writeln(f[i]);
writeln(s);
end.
二分图匹配
var
n,m,i,j,ans:longint;
a:array[1..200,0..200]of longint;
b:array[1..200]of longint;
flag:array[1..200]of longint;
function can(x:longint):boolean;
var
ii:longint;
begin
if flag[x]=i then exit(false);
flag[x]:=i;
for ii:=1 to a[x,0] do
if (b[a[x,ii]]=0)or (can(b[a[x,ii]]))then begin
b[a[x,ii]]:=x;
exit(true);
end;
exit(false);
end;
begin
readln(n,m);
for i:=1 to n do begin
read(a[i,0]);
for j:=1 to a[i,0]do read(a[i,j]);
end;
for i:=1 to n do
if can(i)then inc(ans);
writeln(ans);
close(input);
close(output);
end.
dij迪杰斯克拉(最短路) (cj jzoj 2006)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define INF 2147483647
using namespace std;
int a[2001][2001];
int d[2001][2],b[20001];
bool bz[2001];
int n,m,t,k,ans=0,ans1=0,st;
void dij(int x,int y)
{
memset(bz,false,sizeof(bz));
d[x][y]=0;
st=x;
bz[x]=true;
for (int i=1;i<n;i++)
{
for (int j=1;j<=n;j++)
if (j!=st && a[x][j]!=0 && (d[j][y]==0 || (a[x][j]+d[x][y]<d[j][y])))
d[j][y]=a[x][j]+d[x][y];
int Min=INF;
x=0;
for (int j=1;j<=n;j++)
if (not bz[j] && d[j][y]!=0 && d[j][y]<Min)
{
Min=d[j][y];
x=j;
}
bz[x]=true;
}
}
int main()
{
freopen("escape.in","r",stdin);
freopen("escape.out","w",stdout);
int x,y,z;
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
a[x][y]=z;
a[y][x]=z;
}
scanf("%d",&k);
for (int i=1;i<=k;i++)
scanf("%d",&b[i]);
dij(1,1);
dij(n,2);
for(int i=1;i<=k;i++)
{
int te;
if (d[b[i]][1]<=t || d[b[i]][2]<=t) ans++;
if (d[b[i]][1]>d[b[i]][2]) te=d[b[i]][2];
else te=d[b[i]][1];
if (te>ans1) ans1=te;
}
printf("%d\n",ans);
printf("%d\n",ans1);
}