noip考前模板大整理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noip考前模板大整理相关的知识,希望对你有一定的参考价值。

//归并排序求逆序对
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,b[100005];
ll ans;
int a[100005];
void merge_sort(int l,int r) {
    if(l==r)return;
    int mid=(l+r)>>1;
    int i=l,j=mid+1,cnt=l;
    merge_sort(l,mid);
    merge_sort(mid+1,r);
    while(i<=mid&&j<=r) {
        if(a[i]<=a[j])b[cnt++]=a[i++];
        else {
            b[cnt++]=a[j++];
            ans+=(mid-i+1);
        }
    }
    while(i<=mid)b[cnt++]=a[i++];
    while(j<=r)b[cnt++]=a[j++];
    for(register int s=l; s<=r; ++s)a[s]=b[s];
}
int main() {
    scanf("%d",&n);
    for(register int i=1; i<=n; ++i) {
        scanf("%d",&a[i]);
    }
    merge_sort(1,n);
    printf("%lld",ans);
    return 0;
}


//SPFA模板pre为记录路径,同dij
#include<bits/stdc++.h>
using namespace std;
int n,m;
int pre[50005];
bool book[1505];
int a,b,v,siz;
int head[50005],lu[100005];
int cnt,dist[1505];
struct node {
    int v,dis,next;
} e[50005];
void add(int u,int v,int dis) {
    ++cnt;
    e[cnt].v=v;
    e[cnt].dis=dis;
    e[cnt].next=head[u];
    head[u]=cnt;
}
void print(int nn) {
    if(nn==1)return;
    else {
        lu[++siz]=pre[nn];
        print(pre[nn]);
    }
}
void SPFA() {
    memset(book,false,sizeof(book));
    memset(dist,0x3f,sizeof(dist));
    queue<int>q;
    q.push(1);
    book[1]=1;
    //pre[1]=0;
    dist[1]=0;
    while(!q.empty()) {
        int u=q.front();
        q.pop();
        book[u]=0;
        for(register int i=head[u]; i; i=e[i].next) {
            int v=e[i].v;
            if(dist[v]>dist[u]+e[i].dis) {
                dist[v]=dist[u]+e[i].dis;
                pre[v]=u;
                if(!book[v]) {
                    q.push(v);
                    book[v]=1;
                }
            }
        }
    }
}
int main() {
    scanf("%d%d",&n,&m);
    for(register int i=1; i<=m; ++i) {
        scanf("%d%d%d",&a,&b,&v);
        add(a,b,v);
    }
    SPFA();
    printf("%d\n",dist[n]);
    print(n);
    for(register int i=siz; i>=1; --i)
        printf("%d->",lu[i]);
    cout<<n;
    return 0;
}


//SPFA判负环
int tim[maxn];
bool spfa(int s) {
    d[s]=0;
    q.push(s);
    used[s]=1;
    while(!q.empty()) {
        int x=q.front();
        q.pop();
        used[x]=0;
        for(int i=first[x]; i; i=next[i]) {
            int u=hh[i].t;
            if(d[u]>d[x]+hh[i].c) {
                d[u]=d[x]+hh[i].c;
                if(!used[u]) {
                    if(++tim[u]>n)
                        return false;
                    q.push(u);
                    used[u]=1;
                }
            }
        }
    }
    return true;
}


//DIJ模板
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 10009
#define inf 2147483647
using namespace std;
int n,m,s,sumedge;
int dis[maxn],vis[maxn],head[maxn];
struct Edge { //邻接表储存
    int x,y,z,nxt;
    Edge(int x=0,int y=0,int z=0,int nxt=0):
        x(x),y(y),z(z),nxt(nxt) {}
} edge[maxn*51];
void add(int x,int y,int z) {
    edge[++sumedge]=Edge(x,y,z,head[x]);
    head[x]=sumedge;
}
void di() {
    for(int i=1; i<=n; i++)dis[i]=inf;
    dis[s]=0;
    for(int i=1; i<=n; i++) {
        int k,mn=inf;
        for(int j=1; j<=n; j++) {
            if(!vis[j]&&dis[j]<mn) {
                mn=dis[j];
                k=j;
            }
        }
        if(mn==inf)break;
        vis[k]=true;
        for(int j=head[k]; j; j=edge[j].nxt) {
            int v=edge[j].y;
            if(!vis[v]&&dis[v]>dis[k]+edge[j].z)
                dis[v]=dis[k]+edge[j].z;
        }
    }
}
int main() {
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1; i<=m; i++) {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
    }
    di();
    for(int i=1; i<=n; i++)printf("%d ",dis[i]);
    return 0;
}





//floyd
memset(dis,0x3f,sizeof(dis));
for(int i=1; i<=n; i++)dis[i][i]=0;
for(int k=1; k<=n; k++)
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);



//最小生成树kruskal
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 5020
#define M 200008
using namespace std;
int n,m,ans;
int tot;
int fa[N];
struct E {
    int x,y,z;
} e[M];
bool cmp(E a,E b) {
    return a.z<b.z;
}
int f(int x) {
    return fa[x]==x?x:fa[x]=f(fa[x]);
}
int main() {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=m; i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
    for(int i=1; i<=n; i++)fa[i]=i;
    sort(e+1,e+m+1,cmp);
    for(int i=1; i<=m; i++) {
        int x=e[i].x,y=e[i].y;
        int fx=f(x),fy=f(y);
        if(fx!=fy) {
            fa[fx]=fy;
            ans+=e[i].z;
            if(++tot==n-1)break;
        }
    }
    if(tot!=n-1)cout<<"orz\n";
    else printf("%d\n",ans);
    return 0;
}


//欧拉筛法
void prime() {
    check[1]=1;
    for(int i=2; i<=n; i++) {
        if(!check[i])prim[++cnt]=i;//这个if语句后面没有大括号!!
        for(int j=1; j<=cnt&&prim[j]*i<=n; j++) {
            check[i*prim[j]]=true;
            if(i%prim[j]==0)break;
        }
    }
}


//素数判断
bool check(int x) {
    if(x<=1)return false;
    for(int i=2; i*i<=x; i++)
        if(x%i==0)return false;
    return true;
}


//gcd
int gcd(int x,int y) {
    return y==0?x:gcd(y,x%y);
}


//多组gcd预处理
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,g[100][100];
int main() {
    scanf("%d",&n);
    for(int i=1; i<=n; i++) {
        g[i][i]=i;
        g[i][0]=g[0][i]=i;
        for(int j=1; j<i; j++) {
            g[j][i]=g[i][j]=g[j][i%j];
        }
    }
    return 0;
}


//最长回文串
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1e7+5;
char s[maxn*2],str[maxn*2];
int Len[maxn*2],len;

void getstr() {
    int k=0;
    str[k++]=$;
    for(int i=0; i<len; i++)
        str[k++]=#,
                 str[k++]=s[i];
    str[k++]=#;
    len=k;
}
void Manacher() {
    getstr();
    int mx=0,id;
    for(int i=1; i<len; i++) {
        if(mx>i) Len[i]=min(Len[2*id-i],mx-i);
        else Len[i]=1;
        while(str[i+Len[i]]==str[i-Len[i]])
            Len[i]++;
        if(Len[i]+i>mx)
            mx=Len[i]+i,id=i;
    }
}
int main() {
    scanf("%s",&s);
    len=strlen(s);
    Manacher();
    int ans=1;
    for(int i=1; i<len; i++) ans=max(ans,Len[i]);
    printf("%d\n",ans-1);
    return 0;
}

//分解质因素
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int main() {
    long long n;
    scanf("%lld",&n);
    for(long long i=2; i<=n; i++) {
        while(n!=i) {
            if(n%i==0) {
                printf("%lld*",i);
                n=n/i;
            } else break;
        }
    }
    printf("%lld",n);
    return 0;
}

//求树上两点距离,无向图根节点随意,有向的根入度为0
#include<bits/stdc++.h>
using namespace std;
int n;
int deep[100005];
int ru[100005];
int fa[100005];
int head[100005],cnt;
int dist[100005];
struct node {
int v,w,next;
} e[200005];
inline void add(int u,int v,int w) {
e[++cnt].next=head[u];
e[cnt].v=v;
e[cnt].w=w;
head[u]=cnt;
}
inline void Deep_pre(int x,int dep) {//求深度
deep[x]=dep;
for(register int i=head[x]; i; i=e[i].next) {
if(e[i].v==fa[x]) continue;
fa[e[i].v]=x;
dist[e[i].v]=dist[x]+e[i].w;
Deep_pre(e[i].v,dep+1);
}
}
inline int lca(int x,int y) {//暴力lca
if(deep[x]>deep[y])swap(x,y);
while(deep[x]!=deep[y]) {
y=fa[y];
}
while(x!=y) {
x=fa[x];
y=fa[y];
}
return x;
}
int main() {
scanf("%d",&n);
for(register int i=1,u,v,w; i<n; ++i) {
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
int root=1;
fa[root]=0;
Deep_pre(root,1);
int m,ui,vi;
scanf("%d",&m);
for(register int i=1; i<=m; ++i) {
scanf("%d%d",&ui,&vi);
int LCA=lca(ui,vi);
// printf("%d\n",deep[ui]+deep[vi]-2*deep[LCA]);//两点距离
printf("%d\n",dist[ui]+dist[vi]-2*dist[LCA]);//两点距离
}
return 0;
} 

//Tarjan lca
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,s;
int head[500005],hd[500005];
int x,y,u,v,cnt,cnt1;
bool vis[500005];
int fa[500005],ans[500005];
struct node {
    int v,next;
} e[500005<<1];
struct edge {
    int v,next,num;
} ee[500005<<1];
inline int find(int x) {
    return x==fa[x]?x:fa[x]=find(fa[x]);
}
inline void Union(int x,int too) {
    int r1=find(x),r2=find(too);
    if(r1!=r2)fa[r2]=r1;
}
inline void add(int u,int v) {
    e[++cnt].next=head[u];
    e[cnt].v=v;
    head[u]=cnt;
}
inline void ask(int u,int v,int num) {
    ee[++cnt1].next=hd[u];
    ee[cnt1].num=num;
    ee[cnt1].v=v;
    hd[u]=cnt1;
}
inline void dfs(int x) {
    vis[x]=true;
    for(register int i=hd[x]; i; i=ee[i].next) {
        if(vis[ee[i].v])ans[ee[i].num]=find(ee[i].v);
    }
    for(register int i=head[x]; i; i=e[i].next) {
        if(!vis[e[i].v]) {
            dfs(e[i].v);
            Union(x,e[i].v);
        }
    }
}
int main() {
    memset(vis,false,sizeof(vis));
    scanf("%d%d%d",&n,&m,&s);
    for(register int i=1; i<=n; ++i)fa[i]=i;
    for(register int i=1; i<n; ++i) {
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    for(register int i=1; i<=m; ++i) {
        scanf("%d%d",&u,&v);
        ask(u,v,i);
        ask(v,u,i);
    }
    dfs(s);
    for(register int i=1; i<=m; ++i)printf("%d\n",ans[i]);
    return 0;
}

//快速米
ll qpow(ll x,ll y,ll p) { // x^y mod p
    ll ret=1;
    while(y) {
        if(y&1)ret = ret * x % p;
        x=x*x%p;
        y>>=1;
    }
    return ret;
}

//图上dfs 
int head[10005]={0};
int cnt=0;
int vis[10005];
struct edge
{
    int to;
    int nxt=0;
}bian[100005];
void add(int a,int b)
{
    cnt++;
    bian[cnt].to=b;
    bian[cnt].nxt=head[a];
    head[a]=cnt;
}
void dfs(int x)
{
    printf("%d\n",x);
    vis[x]=1;
    for(int i=head[x];i!=0;i=bian[i].nxt)
    {
        if(!vis[bian[i].to]) dfs(bian[i].to);
    }
}
dfs(1);


//最小环 
#include<bits/stdc++.h>
#define v (ti[x])
#define ll long long
using namespace std;
int n,ans(1<<30);int ass=0;
bool vis[200005];
int ti[200005],DEP[200005];
inline void dfs(int x,int steps) {
    if(ass>=300000) {
        printf("%d\n",ans);
        exit(0);
    }
    ass++;
    DEP[x]=steps;
    vis[x]=1;
    if(DEP[v])ans=min(ans,DEP[x]-DEP[v]+1);//有环了
    else dfs(v,steps+1);
    DEP[x]=0;
}
int main() {
    scanf("%d",&n);
    for(register int i=1; i<=n; ++i) {
        scanf("%d",&ti[i]);
    }
    for(register int i=1; i<=n; ++i) {
        if(!vis[i])dfs(i,1);
    }
    printf("%d\n",ans);
    return 0;
}


//堆优化dij
#include<cstdio>
#include<queue>
#include<cstring>
#define inf (0x3f3f3f3f)
struct node {
    int cur,x;
    bool operator<(const node& b) const  {
        return this->x>b.x;
    }
};
struct edge {
    int v,w,pre;
} e[10000000];
std::priority_queue<node> Q;
bool inQ[100000];
int dis[10000],cnt;
int head[100000];
void adde(int u,int v,int w) {
    e[++cnt]=(edge) {v,w,head[u]},head[u]=cnt;
    e[++cnt]=(edge) {u,w,head[v]},head[v]=cnt;
}
int dij(int s,int t) {
    memset(dis,0x3f,sizeof dis);
    dis[s]=0;
    inQ[s]=1;
    Q.push((node) {s,0});
    while(!Q.empty()) {
        node me=Q.top();
        Q.pop();
        inQ[me.cur]=0;
        if(me.x==inf) continue;
        for(int i=head[me.cur]; i; i=e[i].pre) {
            int v=e[i].v;
            if(dis[v]>dis[me.cur]+e[i].w) {
                dis[v]=dis[me.cur]+e[i].w;
                if(!inQ[v]) {
                    inQ[v]=1;
                    Q.push((node) {
                        v,dis[v]
                    });
                }
            }
        }
    }
    return dis[t]==inf?-1:dis[t];
}

int main() {
    int num,u,v,w,s,t;
    scanf("%d",&num);
    while(num--) {
        scanf("%d%d%d",&u,&v,&w);
        adde(u,v,w);
    }
    scanf("%d%d",&s,&t);
    printf("%d\n",dij(s,t));
    return 0;
}

 

以上是关于noip考前模板大整理的主要内容,如果未能解决你的问题,请参考以下文章

noip2016考前模板

NOIP2017 酱油送命记

NOIP考前临时抱佛脚(算是考前日记吧)

NOIP考纲总结+NOIP考前经验谈

NOIP 考前 队列复习

NOIP考前注意事项