常见模板(欧拉筛素数,最小生成树,快排,并查集,单源最短路)

欧拉筛素数:

#include<cstdio>

#define maxn 10000000+10

using namespace std;

int n,prime[5000001],num_prime=0,m;

bool if_prime[maxn];

void euler(int limit)
{
    for(int i=2;i<=limit;i++)
    {
        if(!if_prime[i]) prime[++num_prime]=i;
        for(int j=1;prime[j]*i<=limit&&j<=num_prime;j++)
        {
            if_prime[i*prime[j]]=true;
            if(i%prime[j]==0) break;
        }
    }
}

int main()
{
    if_prime[1]=true;
    scanf("%d%d",&n,&m);
    euler(n);
    int cur_1;
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&cur_1);
        if(!if_prime[cur_1]) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

单源最短路:

#include<queue>
#include<cstdio>

#define INF 2147483647LL

using namespace std;

struct node {
    int to,dis,next;
};
struct node edge[500005];

int n,m,num,head[10001],dis_1[10001];

inline void edge_add(int from,int to,int dis)
{
    num++;
    edge[num].to=to;
    edge[num].dis=dis;
    edge[num].next=head[from];
    head[from]=num;
}

void SPFA(int start)
{
    queue<int>que;
    bool if_in_spfa[10001];
    for(int i=1;i<=n;i++) dis_1[i]=INF,if_in_spfa[i]=false;
    dis_1[start]=0,if_in_spfa[start]=true;
    que.push(start);
    while(!que.empty())
    {
        int cur_1=que.front();
        que.pop();
        for(int i=head[cur_1];i;i=edge[i].next)
        {
            if(dis_1[cur_1]+edge[i].dis<dis_1[edge[i].to])
            {
                dis_1[edge[i].to]=edge[i].dis+dis_1[cur_1];
                if(!if_in_spfa[edge[i].to])
                {
                    if_in_spfa[edge[i].to]=true;
                    que.push(edge[i].to);
                }
            }
        }
        if_in_spfa[cur_1]=false;
    }
}

int main()
{
    int s;
    scanf("%d%d%d",&n,&m,&s);
    int from,to,dis;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&from,&to,&dis);
        edge_add(from,to,dis);
    }
    SPFA(s);
    for(int i=1;i<=n;i++) printf("%d ",dis_1[i]);
    return 0;
}

最小生成树:

#include<cstdio>
#include<algorithm>

using namespace std;

struct node {
    int from,to,dis;
};
struct node edge[200001];

int num_head,num_edge,f[5001],num_2=0;

int find(int x)
{
    if(f[x]==x) return x;
    else return f[x]=find(f[x]);
}

inline void edge_add(int from,int to,int dis)
{
    num_2++;
    edge[num_2].to=to;
    edge[num_2].dis=dis;
    edge[num_2].from=from;
}

bool cmp(struct node a,struct node b){return a.dis<b.dis;}

int main()
{
    scanf("%d%d",&num_head,&num_edge);
    int from,to,dis;
    for(int i=1;i<=num_edge;i++)
    {
        scanf("%d%d%d",&from,&to,&dis);
        edge_add(from,to,dis);
    }
    for(int i=1;i<=num_head;i++) f[i]=i;
    sort(edge+1,edge+num_edge+1,cmp);
    int head_1=0,num_1=0,sum=0;
    while(num_1<num_edge)
    {
        num_1++;
        int x=find(edge[num_1].from),y=find(edge[num_1].to);
        if(x!=y)
        {
            sum+=edge[num_1].dis;
            head_1++;
            f[x]=y;
        }
        if(head_1==num_head-1) break;
    }
    if(head_1==num_head-1) printf("%d\n",sum);
    else printf("orz\n");
    return 0;
}

并查集:

#include<cstdio>

using namespace std;

int n,m,f[10001];

int find(int x)
{
    if(f[x]==x) return x;
    else return f[x]=find(f[x]);
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) f[i]=i;
    int now_1,now_2,cur_1;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&cur_1,&now_1,&now_2);
        now_1=find(now_1),now_2=find(now_2);
        if(cur_1==1) f[now_1]=now_2;
        else now_1==now_2?printf("Y\n"):printf("N\n");
    }
    return 0;
}

快排:

#include<cstdio>

using namespace std;

int i[100001],n;

void Qsort(int t1,int t2)
{
    int x=t1,y=t2,m=i[(t1+t2)>>1],t;
    do
    {
        while (i[x]<m)
          x++;
        while (i[y]>m)
          y--;
        if (x<=y)
        {
            t=i[x];
            i[x]=i[y];
            i[y]=t;
            x++;
            y--;
        }
    }
    while (x<=y);
    if (t1<y)
      Qsort(t1,y);
    if (x<t2)
      Qsort(x,t2);
}
int main()
{
    scanf("%d",&n);
    for(int a=1;a<=n;a++) scanf("%d",&i[a]);
    Qsort(1,n);
    for(int a=1;a<=n;a++) if(a==1) printf("%d",i[a]);
                            else printf(" %d",i[a]);
    printf("\n");
    return 0;
}
时间: 2024-10-06 08:07:31

常见模板(欧拉筛素数,最小生成树,快排,并查集,单源最短路)的相关文章

欧拉筛素数+求欧拉函数

线性筛法 prime记录素数,num_prime素数下标 它们保证每个合数只会被它的最小质因数筛去 a[0]=a[1]=1; for(int i=2;i<=n;i++) { if(!a[i]) prime[num_prime++]=i; for(int j=0;j<num_prime&&i*prime[j]<=n;j++) { a[i*prime[j]]=1; if(!(i%prime[j])) break; } } } 欧拉函数 是 积性函数:对于任意互质的整数a和b有

[CF261E]Maxim and Calculator_搜索_欧拉筛素数_动态规划

Maxim and Calculator 题目链接:https://www.luogu.org/problem/CF261E 数据范围:略. 题解: 考试的时候只会暴力,学弟太强了$\%\%\% Orz$. 感觉直接处理不太好处理,得想到所有有可能被这种操作在$100$步表示出来. 先打个表. 之后就随便$dpdp$就好了,关键是你得想到所有合法的数非常小. 我反正是没想到..... 代码: #include <bits/stdc++.h> #define N 3000010 using na

素数筛&amp;&amp;欧拉筛 BZOJ2818 Gcd BZOJ2190 [SDOI2008]仪仗队

折腾了一晚上很水的数论,整个人都萌萌哒 主要看了欧拉筛和素数筛的O(n)的算法 这个比那个一长串英文名的算法的优势在于没有多次计算一个数,也就是说一个数只筛了一次,主要是在%==0之后跳出实现的,具体的解释看的迷迷糊糊,特别是欧拉函数的求解 http://blog.csdn.net/lerenceray/article/details/12420725 代码如下 1 void ES(){ 2 for(int i=2;i<n;i++){ 3 if (!pd[i]){ 4 prime[++top]=

POJ 3126 Prime Path (bfs+欧拉线性素数筛)

Description The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices. - It is a matter of security to change such things every now

线性筛素数(欧拉筛)

线性筛素数(欧拉筛) 欧拉筛为啥是\(O(n)\)的呢?我们先来看看代码. #include <cstdio> using namespace std; const int maxn=10000000; int n, m, prime[maxn], isnt_prime[maxn], tot; void get_prime(int n){ isnt_prime[0]=isnt_prime[1]=1; for (int i=2; i<=n; ++i){ //当前数是所有数小于n的数而不只是

欧拉筛 线性筛 素数+莫比乌斯的mu[]

https://blog.csdn.net/qq_39763472/article/details/82428602 模板来自https://blog.csdn.net/Avalon_cc/article/details/81663214 bool isP[N]; int P[N], ind; void Euler() { mem(isP,1); mu[1]=1; ind=0; for(int i=2;i<N;i++) { if(isP[i]) P[ind++]=i, mu[i]=-1; for

素数表的获取(埃氏筛和欧拉筛)

Eratosthenes筛法(埃氏筛) 时间复杂度:O(nlognlogn) 思路 代码 const int maxn=1e6+10; //表长 int prime[maxn],cnt=0; //prime数组存放所以素数,cnt为素数个数 bool st[maxn]; //false为素数 void get_prime(int n){ for(int i=2;i<=n;i++){ if(!st[i]){ prime[cnt++]=i; //把素数i存到prime数组中 for(int j=i+

弄了个欧拉筛求素数

最近遇到某方面的内容和欧拉筛有关系,于是就自己重新弄了个欧拉筛,当然记得以前自己曾经写过一次,这次自己完全写起来发现和第一次写的主体方面还是差不多(就那么一个细微的区别),可以参考一下 程序代码: #include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h> void nodeMal( void** ,size_t );void nodeFree( void** );void 

欧拉筛(线性筛)

素数筛,就是按照顺序把合数踢掉,剩下的是素数. 欧拉筛是一种O(n)求素数的筛法.他避免了埃拉特斯特尼筛法对同一数的多次筛除. 欧拉筛的原理是只通过数的最小质因数筛数. 先上代码: #include <cstdio> using namespace std; const int maxn=10000000; int n, m, prime[maxn], isnt_prime[maxn], tot; void get_prime(int n){ isnt_prime[0]=isnt_prime[