首页 > 代码库 > noip复习模板

noip复习模板

我只会这么多

tarjan:codevs 1332

void tarjan(int u)
{
    dfn[u]=low[u]=Time++; s.push(u);
    for(int i=head[u];~i;i=nxt[i])
    {
        int v=to[i];
        if(!dfn[v]) tarjan(v);
        else if(dfn[v]!=-1) low[u]=Min(low[u],low[v]);
    }
    if(dfn[u]==dfn[v])
    {
        while(!s.empty())
        {
            int x=s.top(); s.pop();
            dfn[x]=-1;
            tot++;
            if(x==u) break;
        }
    }
}

spfa codevs 2038

#include<iostream>
#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std;
const int inf=0x3f3f3f3f;
int cnt=-1,n,e,s,t,ans=inf,p;
int head[500010],to[500010],w[500010],nxt[500010],d[500010],used[500010],pos[500010];
int Min(int x,int y)
{
    return x<y?x:y;
}
void Init()
{
    memset(head,-1,sizeof(head));
    memset(nxt,-1,sizeof(nxt));
}
void link(int u,int v,int l)
{
    nxt[++cnt]=head[u];
    head[u]=cnt;
    to[cnt]=v;
    w[cnt]=l;
}
void spfa(int s)
{
    queue<int>q;
    memset(d,inf,sizeof(d));
    q.push(s); d[s]=0; used[s]=1;
    while(!q.empty())
    {
        int u=q.front(); q.pop(); used[u]=0;
        for(int i=head[u];~i;i=nxt[i])
        {
            int v=to[i],val=w[i];
            if(d[v]>d[u]+val)
            {
                d[v]=d[u]+val;
                if(!used[v])
                {
                    q.push(v);
                    used[v]=1;
                }
            }
        }
    }
    int tot=0;
    for(int i=1;i<=n;i++)
    {
        tot+=d[pos[i]];
    }
    ans=Min(ans,tot);
}
int main()
{
    scanf("%d%d%d",&n,&p,&e);
    for(int i=1;i<=n;i++)
    {
        int u; scanf("%d",&pos[i]);
    }
    Init();
    for(int i=1;i<=e;i++)
    {
        int u,v,c; scanf("%d%d%d",&u,&v,&c);
        link(u,v,c); link(v,u,c);
    }
    for(int i=1;i<=p;i++) 
    {
        spfa(i);
    }
    printf("%d",ans);
    return 0;
}

lca 1787

#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
int n,m,u,v,a,b,c,ans,temp1,cnt=-1;
int dep[1000010],head[1000010],to[1000010],nxt[1000010];
int fa[23][1000010];
void Init()
{
    memset(head,-1,sizeof(head));
    memset(nxt,-1,sizeof(nxt));
    memset(fa,-1,sizeof(fa));
}
int abs(int x)
{
    return x>0?x:-x;
}
void link(int u,int v)
{
    nxt[++cnt]=head[u]; head[u]=cnt;
    to[cnt]=v;
}
void dfs(int u,int d)
{
    dep[u]=d; 
    for(int i=head[u];~i;i=nxt[i])
    {
        int v=to[i];
        if(!dep[v])
        {
            fa[0][v]=u;
            dfs(v,d+1);
        }
    }
}
int lca(int u,int v)
{
    if(dep[u]<dep[v]) swap(u,v);
    int deep=dep[u]-dep[v];
    for(int i=22;i>=0;i--)
    {
        if(deep&(1<<i)) u=fa[i][u];
    }
    if(u==v) return u;
    for(int i=22;i>=0;i--)
    {
        if(fa[i][u]!=fa[i][v]) 
        {
            u=fa[i][u];
            v=fa[i][v];
        }
    }
    return fa[0][u];
}
inline int calc(int x,int y)
{
    int temp=lca(x,y);
    return abs(dep[x]-dep[temp])+abs(dep[y]-dep[temp]);
}
int main()
{
    scanf("%d%d",&n,&m);
    Init();
    for(int i=1;i<n;i++)
    {
        int u,v; scanf("%d%d",&u,&v);
        link(u,v); link(v,u);
    }
    dfs(1,0);
    for(int i=1;i<=22;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(fa[i-1][j]!=-1) fa[i][j]=fa[i-1][fa[i-1][j]];
        }
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&a,&b,&c);
        int x=lca(a,b);
        int y=lca(b,c);
        int z=lca(c,a);
        if(x==y)
            temp1=z;
        else
        if(y==z)
            temp1=x;
        else
        if(x==z)
            temp1=y;
        ans=calc(a,temp1)+calc(b,temp1)+calc(c,temp1);
        printf("%d %d\n",temp1,ans); 
    }
    return 0;
} 

二分 跳石头

#include<iostream>
#include<stdio.h>
using namespace std;
int n,m,ans,L;
int a[500010],mark[500010];
bool C(int x)
{
    int last=0,tot=0;
    for(int i=1;i<=n;i++)
    {
        mark[i]=0;
        if(a[i]-a[last]<x)
        {
            tot++; 
            mark[i]=1;
        }
        else last=i;
    }
    last=n+1;
    for(int i=n;i>=1;i--)
    {
        if(a[last]-a[i]<x&&!mark[i]) tot++; 
        else if(a[last]-a[i]>=x) break;
    }
    return tot<=m;
}
int main()
{
    scanf("%d%d%d",&L,&n,&m);
    a[0]=0; a[n+1]=L+1;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    int l=0,r=L+1,mid;
    while(r-l>1)
    {
        mid=(l+r)/2;
        if(C(mid)) {l=mid;ans=mid;}
        else r=mid;
    }
    if(C(ans+1)) ans++;
    printf("%d",ans);
    return 0;
}

线段树

1012

#include<iostream>
#include<cstdio>
using namespace std;
const int inf=1<<29;
int m,d,t,size;
int tree[6000010]; 
int Max(int x,int y)
{
    return x>y?x:y;
}
void update(int l,int r,int x,int pos,int num)
{
    if(l==r) 
    {
        tree[x]=num;
        return;
    }
    if(pos>(l+r)/2) update((l+r)/2+1,r,x*2+1,pos,num);
    if(pos<=(l+r)/2) update(l,(l+r)/2,x*2,pos,num);
    tree[x]=Max(tree[x],Max(tree[x*2],tree[x*2+1]));
}
int query(int l,int r,int x,int a,int b)
{
    if(l>b||r<a) return -inf;
    if(l>=a&&r<=b) return tree[x];
    return Max(query(l,(l+r)/2,x*2,a,b),query((l+r)/2+1,r,x*2+1,a,b));
}
int main()
{
    scanf("%d%d",&m,&d);
    for(int i=1;i<=m;i++)
    {
        char s[10]; scanf("%s",s);
        if(s[0]==A)
        {
            int n,num; scanf("%d",&n); size++;
            num=(n+t)%d;
            update(1,m,1,size,num);
        }
        else if(s[0]==Q)
        {
            int l; scanf("%d",&l);
            t=query(1,m,1,size-l+1,size);
            printf("%d\n",t);
        }
    }
//    for(int i=1;i<=3;i++) cout<<tree[i]<<" "; 
    return 0;
}

快速幂:

#include<iostream>
using namespace std;
int n,m,k,x;
int power(int k)
{
    int t=10,ret=1;
    while(k>0)
    {
        if(k%2==1) ret*=t;
        t*=t; k/=2; 
    }
    return ret;
}
int main()
{
    cin>>k;
    cout<<power(k);
    return 0;
}

 

noip复习模板