[置顶] 模板(一直更新中)

(Languages: C,C++,Pascal)

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);
}

你可能感兴趣的:([置顶] 模板(一直更新中))