【持续更新中······】 各种模板+神奇黑科技

3 篇文章 0 订阅
1 篇文章 0 订阅

读入优化:

int GET()
{
    int x=0,f=1;
    char c;
    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 ksm(int a,int b,int c)
{
    int ans=1;
    a=a%c;
    while (b>0)
    {
        if (b&1) ans=(ans*a)%c;
        b=b/2;
        a=(a*a)%c; 
    }
    return ans;
}

RMQ:

int seat_rmq(int i,int j)
{
    int k=log(i+j-1)/log(2);
    return min(f[i][k],f[i-(1<<k)+1][k]);
}
while (tmp<=n)
{
    tmp*=2;
    k++;
}
for (j=1;j<=k;j++)
    for (i=1;i<=n;i++)
        if (i+(1<<(i-1))-1<=n)
        f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);

tarjan:

void tarjan(int u)
{
    int i;
    low[u]=dfn[u]=++insex;
    instack[u]=true;
    stack[++tot]=u;
    for (i=head[u];i;i=e[i].next)
    {
        int v=e[i].to;
        if (!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[v],low[u]);
        }
        else if (instack[v])
        {
            low[u]=min(low[u],dfn[v]);
        }
    }
    if (low[u]==dfn[u])
    {
        int tmp=0;
        while (tmp!=u)
        {
            tmp=stack[tot--];
            instack[tmp]=false;
        }
    }
}
void slove()
{
    int i;
    memset(dfn,0,sizeof(dfn));
    for (i=1;i<=n;i++)
        if (!dfn[i])
            tarjan(i);
}

邻接表:

void add(int from,int to)
{
    ++e_num;
    e[e_num].from=from;
    e[e_num].to=to;
    e[e_num].next=head[from];
    head[from]=e_num;
}

Dijkstra:

    memset(flag,false,sizeof(flag));
    c[1]=0;
    for (i=1;i<=n;i++)
    {
        minn=maxx;
        k=0;
        for (j=1;j<=n;j++)
            if ((!flag[j])&&(c[j]<minn))
            {
                minn=c[j];
                k=j;
            }
        if (k==0) break;
        flag[k]=true;
        for (j=1;j<=n;j++)
        {
            if (c[k]+f[k][j]<c[j])
                c[j]=c[k]+f[k][j];
        }
    }

floyed

    for (k=1;k<=n;k++)
        for (i=1;i<=n;i++)
            for (j=1;j<=n;j++)
                if ((i!=j)&&(j!=k)&&(i!=k))
                f[i][j]=min(f[i][j],f[i][k]+f[k][j]);

SPFA:

void SPFA()
{
        memset(vis,false,sizeof(vis));
    for (i=1;i<=n;i++)
        dis[i]=maxx;
    dis[1]=0;
    q[1]=1;
    vis[1]=true;
    int top=0,tail=1;
    while (top<tail)
    {
        top++;
        int u=q[top];
        vis[u]=false;
        for (i=head[u];i;i=e[i].next)
        {
            if (dis[u]+e[i].dis<dis[e[i].to])
            {
                dis[e[i].to]=dis[u]+e[i].dis;
                if (!vis[e[i].to])
                {
                    tail++;
                    q[tail]=e[i].to;
                    vis[e[i].to]=true;
                }
            }
        }
    }
}

数据生成器:

#include<bits/stdc++.h>
using namespace std;
#define random(a,b) ((a)+rand()%((b)-(a)+1))

stringstream ss;


int main( int argc, char *argv[] )
{ 
    int seed=time(NULL);
    if(argc)
    {
        ss.clear();
        ss<<argv[1];
        ss>>seed;
    }
    srand(seed);
    //以上为随机数初始化,请勿修改
    //random(a,b)生成[a,b]的随机整数

    //以下写你自己的数据生成代码 

    printf("\n");
    return 0;
}

辗转相除法(欧几里得):

void gcd(int a,int b)
{
    if (b) return gcd(b,a%b);
    else return a;

扩展欧几里得:

int exgcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    int r=exgcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-a/b*y;
    return r;
}

Eratosthenes筛法:

void eratosthenes_sieve(int n)
{
    totPrimes = 0;
    memset(flag, 0, sizeof(flag));

    int sqrtn = sqrt(n + 0.5);
    for (int i = 2; i <= sqrtn; i++) {
        if (!flag[i]) {
            primes[totPrimes++] = i;
            for (int j = i * i; j <= n; j += i) {
                flag[j] = true;
            }
        }
    }
    for (int i = sqrtn + 1; i <= n; i++) {
        if (!flag[i])
            primes[++totPrimes] = i;
    }
}

欧拉筛法:

void euler_sieve(int n)
{
    totPrimes = 0;
    memset(flag, 0, sizeof(flag));

    for (int i = 2; i <= n; i++) {
        if (!flag[i])
            primes[totPrimes++] = i;
        for (int j = 0; i * primes[j] <= n; j++) {
            flag[i*primes[j]] = true;
            if (i % primes[j] == 0)
                break;
        }
    }
}

LCA:

void add(int from,int to)
{
    ++e_num;
    e[e_num].to=to;
    e[e_num].next=head[from];
    head[from]=e_num;
}
void rmq(int t)
{
    int i;
    for (i=1;i<=20;i++)
    {
        if (deep[t]<(1<<i))
            break;
        f[t][i]=f[f[t][i-1]][i-1];
    }
    vis[t]=true;
    for (i=head[t];i;i=e[i].next)
        if (!vis[e[i].to])
        {
            deep[e[i].to]=deep[t]+1;
            f[e[i].to][0]=t;
            rmq(e[i].to);
        }
}
int lca(int x,int y)
{
    int i;
    if (deep[x]<deep[y])
    {
        swap(x,y);
    }
    for (i=20;i>=0;i--)
    {
        if (deep[x]-deep[y]>=(1<<i))
            x=f[x][i];
    }
    if (x==y) return x;
    int u=0;
    while (deep[x]>=(1<<u)) u++;
    for (i=u;i>=0;i--)
        if (f[x][i]!=f[y][i])
        {
            x=f[x][i];
            y=f[y][i];
        }
    return f[x][0];
}
int main()
{
    int i,x,y;
    scanf("%d%d",&n,&m);
    for (i=1;i<=n-1;i++)
    {
        x=get();y=get();
        add(x,y);add(y,x);
    }
    rmq(s);
    for (i=1;i<=m;i++)
    {
        x=get();y=get();
        printf("%d\n",lca(x,y));
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值