2020CSP-S模板

2020CSP—S模板


仅以此篇,纪念一年左右的OI生涯,预祝大家CSP RP++

算法


二分:

   while(l<r)
    {
        int mid  = (l+r)>>1;
        int ans = solve(mid);
        if(ans>m)
        l=mid+1;
        else 
        r=mid;
    }

离散化

for(int i=1;i<=n;i++)
    scanf("%d",&a[i]),b[i]=a[i];
    sort(b+1,b+1+n);
    for(int i=1;i<=n;i++)
    {
        c[i]=lower_bound(b+1,b+1+n,a[i])-b;
    }
    for(int i=1;i<=n;i++)
    printf("%d ",c[i]);
    //a: 500 600 700 1000 50000
    //c: 1 2 3 4 5

归并排序

void msort(int l,int r)
{
    if(l==r) return;
    int mid = (l+r)>>1;
    msort(l,mid),msort(mid+1,r);
    int i=l,j=mid+1,k=i;
    while(i<=mid&&j<=r)
    {
        if(a[i]<=a[j])
        b[k++]=a[i++];
        else
        b[k++]=a[j++];
    }
    while(i<=mid)
    b[k++]=a[i++];
    while(j<=r)
    b[k++]=a[j++];
    for(int p=l;p<=r;p++)
    a[p]=b[p],b[p]=0;
}

深度优先搜索

void dfs(int x)
{
    if(/*剪枝 边界*/)
    return ;
    /*处理*/
    dfs(y);
    /*处理*/
}

宽度优先搜索

void bfs(int s)
{
    q.push(s);
    vis[s]=1;
    while(!q.empty())
    {
        int top = q.front();
        q.pop();
        int y = top + dx; //由top到达的下一个点
        if(!vis[y]) //边界及判重
        {
            ans...//更新答案
            q.push(y);
        } 
    }
}

模拟退火

void SA()
{
    for(double T=100000;T>=1e-15;T*=down)
    {
        x = ansx + rand() * T;
        int now = calc(x);
        int d = now-ans;
        if(now < ans)
        ans = now;
        else if(exp(-d/T)*RAND_MAX>rand())//有一定概率接受新解
        ansx = x;
    }
}

数学


线性筛素数

void euler(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!np[i])
        {
            prime[++cnt]=i;
        }
        for(int j=1;j<=cnt&&i*prime[j]<=n;j++)
        {
            np[i*prime[j]]=1;
            if(i%prime[j]==0) 
            break;
        }

    }
}

GCD

int gcd(int x,int y)
{
    if(y==0) return x;
    else return gcd(y,x%y);
}

EXGCD

int gcd(int a,int b)
{
    if(b==0) 
    {
        x=1;
        y=0;
        return a;
    }
    int d= gcd(b,a%b);
    int k=x;
    x=y;
    y=x-a/b*y;
    return d;
}

组合数递推

  //C n m
    c[1][0]=c[1][1]=0;
    for(int i=2;i<=n;i++)
    {
        c[i][0]=1;
        for(int j=1;j<=n;j++)
        c[i][j]=c[i-1][j]+c[i-1][j-1];
    }

线性筛欧拉函数

void euler(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!np[i])
        {
            prime[++cnt]=i;
            phi[i]=i-1;
        }
        for(int j=1;j<=cnt&&i*prime[j]<=n;j++)
        {
            np[i*prime[j]]=1;
            if(i%prime[j]==0) 
            {
            phi[i*prime[j]] = phi[i]*prime[j];
            break;
            }
            phi[i*prime[j]] = phi[i] * phi[prime[j]];
        }

    }
}

线性求逆元

void ny(int n)
{
    for(int i=1;i<=n;i++)
    {
        inv[i]=((mod-mod/i)*inv[mod%i])%mod;
    }
}

快速幂(非递归)

int qpow(int a,int b)
{
    int ret=1;
    while(b)
    {
        if(b&1)
        ret=ret*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ret;
}

快速幂(递归版)

int qpow(int a,int b)
{
    if(b==0) return 1;
    if(b%2)
    return qpow(a,b/2)*qpow(a,b/2)*a;
    else 
    return qpow(a,b/2)*qpow(a,b/2);
}

图论和树论


链式前向星

void add(int x,int y)
{
    to[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}

Floyd

void Floyd(int n)
{
    memset(f,0x3f,sizeof(f));
    for(int i=1;i<=n;i++) f[i][i]=0;
    //build
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}

SPFA

void spfa(int s)
{
    queue<int> q;
    memset(dist,0x3f,sizeof(dist));
    dist[s]=0;
    q.push(s);
    inq[s]=1;
    while(!q.empty())
    {
        int x = q.front();
        q.pop();
        inq[x]=0;
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            if(dist[y]>dist[x]+v[i])
            {
                dist[y]=dist[x]+v[i];
                if(!inq[y])
                q.push(y),inq[y]=1;
            }
        }
    }

}

Dijkstra堆优化

priority_queue<pair<int,int> > q;
void dij(int s)
{
    memset(dist,0x3f,sizeof(dist));
    memset(v,0,sizeof(v));
    dist[s]=0;
    q.push(make_pair(0,s));
    while(!q.empty())
    {
        int x = q.top().second;
        if(v[x])
            continue;
        v[x]=1;
        for(int i=head[x];i;i=nxt[i])
        {
            int y =to[i];
            if(dist[y]>dist[x]+val[i])
            {
                dist[y]=dist[x]+val[i];
                q.push(make_pair(-dist[y],y));
            }
        }
    }
}

Kruskal

bool cmp(const node&a,const node &b)
{
    return a.val<b.val;
}
int find(int x)
{
    if(f[x]==x) return x;
    else return f[x]=find(f[x]);
}
void Kruskal()
{
    for(int i=1;i<=n;i++) f[i]=i;
    sort(edge+1,edge+1+m,cmp);
    for(int i=1;i<=m;i++)
    {
        int x=edge[i].l,y=edge[i].r;
        int fx=find(x);
        int fy=find(y);
        if(fx==fy)
        continue;
        else
        {
            f[fx]=fy;
            ans+=edge[i].val;
        }
    }
}

树链剖分

int son[maxn],dep[maxn],sz[maxn],fa[maxn];
void dfs1(int x,int f)
{
    sz[x]=1;
    dep[x]=dep[f]+1;
    fa[x]=f;
    for(int i=head[x];i;i=nxt[i])
    {
        int y=to[i];
        if(y==f)
        continue;
        dfs1(y,x);
        sz[x]+=sz[y];
        if(sz[y]>sz[son[x]]) 
        son[x]=y;
    }
}
int top[maxn],idx[maxn],num=0;
void dfs2(int x,int tp)
{
    top[x]=tp;
    idx[x]=++num;
    if(son[x])
    dfs2(son[x],tp);
    for(int i=head[x];i;i=nxt[i])
    {
        int y=to[i];
        if(y!=son[x]&&y!=fa[x])
        dfs2(y,y);
    }
}
int lca(int x,int y)
{
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]])
        swap(x,y);
        x=fa[top[x]];
    }
    return dep[x]<dep[y]?x:y;
}

拓扑排序

void topsort()
{
	queue<int> q;
	for(int i=1;i<=n;i++)
		if(!du[i])
			q.push(i);
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		for(int i=head[x];i;i=nxt[i])
		{
			int y=to[i];
			du[y]--;
			if(!du[y])
				q.push(y);
		}
	}
}

Tarjan

void tarjan(int x)
{
    dfn[x]=low[x]=++tim;
    s.push(x);
    ins[x]=1;
    for(int i=head[x];i;i=nxt[i])
    {
        int y=to[i];
        if(!dfn[y])
        {
            tarjan(y);
            low[x]=min(low[x],low[y]);
        }
        else if(ins[y])
        {
            low[x]=min(low[x],low[y]);
        }
    }
    if(low[x]==dfn[x])
    {
        int cur;
        do{
            cur=s.top();
            s.pop();
            ins[cur]=0;
            sd[cur]=++cnt;
        }while(x!=cur);
    }
}

数据结构


并查集

int find(int x)
{
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy)
		fa[fx]=fy;
}

线段树

void mark(int l,int r,int p,int v)
{
    tr[p]+=(r-l+1)*v;
    lazy[p]+=v;////!!!!!!
}
void pushdown(int l,int r,int p)
{
    int mid = (l+r) >> 1 ;
    mark(l,mid,lson,lazy[p]);
    mark(mid+1,r,rson,lazy[p]);
    lazy[p]=0;
}
void pushup(int p)
{
    tr[p]=tr[lson]+tr[rson];
}
void update(int l,int r,int x,int y,int v,int p)
{
    if(x<=l&&y>=r)
    {
        mark(l,r,p,v);
        return ;
    }
    if(lazy[p])
    pushdown(l,r,p);
    int mid = (l+r)>>1;
    if(x<=mid) update(l,mid,x,y,v,lson);
    if(y>mid) update(mid+1,r,x,y,v,rson);
    pushup(p);
}
int query(int l,int r,int x,int y,int p)
{
    if(x<=l&&y>=r)
    return tr[p];
    if(lazy[p])
    pushdown(l,r,p);
    int ret=0;
    int mid=(l+r)>>1;
    if(x<=mid) ret+=query(l,mid,x,y,lson);
    if(y>mid) ret+=query(mid+1,r,x,y,rson);
    return ret;
}
void build(int l,int r,int p)
{
    if(l==r)
    {
        tr[p]=val[l];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,lson);
    build(mid+1,r,rson);
    pushup(p);
}

树状数组

void update(int x,int k)
{
    for(int i=x;i<=n;i+=i&-i)
    {
        a[i]+=k;
    }
}
int getsum(int x)
{
    int ret=0;
    for(int i=x;i;i-=i&-i)
    {
        ret+=a[i];
    }
    return ret;
}

单调栈

  for(int i=1;i<=n;i++)
    {
        while(top&&a[i]>=a[s[top]])
        {
            p[s[top]]=i;
            top--;
        }
        s[++top]=i;
    }

单调队列(滑动窗口)

for(int i=m;i<=n;i++)
    {
        while(l<=r&&a[i]<=a[q[r]]) r--;
        while(l<=r&&i-q[l]>=m) l++;
        q[++r]=i;
        printf("%d ",a[q[l]]);
    }
posted @ 2020-11-05 21:03  岚默笙  阅读(70)  评论(0编辑  收藏  举报