• 【持续更新】算法竞赛常用模板


    一、动态规划

    1. 经典01背包

    问题: 求背包容量允许范围下,装不同物品(每种物品只可取一次)可得到的最高价值

    for(int i=1;i<=n;i++)
    	for(int j=v;j>=c[i];j--)
    		dp[j]=max(dp[j],dp[j-c[i]]+w[i]);

    2. 经典完全背包

    问题: 求背包容量允许范围下,装不同物品(每种物品可取无限次)可得到的最高价值

    for(int i=1;i<=n;i++)
    	for(int j=c[i];j<=v;j--)//必须正序
    		dp[j]=max(dp[j],dp[j-c[i]]+w[i]);

    二、数学

    1. 快速幂

    \(x\)是底数,\(n\)是指数,\(p\)为取模数
    ①普通快速幂

    long long qpow(long long x,long long n,long long p){
    	if(!n)return 1;
    	long long ans=qpow((x%p)*(x%p)%p,n/2,p)%p;
    	if(n%2)ans=ans*(x%p)%p;
    	return ans;
    }
    

    ②矩阵快速幂

    三、图论

    1. 图的存储:

    ①邻接矩阵存边:略
    ②邻接表(vector实现)存边:

    //定义
    struct node{
    	int to;//边通向的点的编号
    	int val;//边权
    }tmp;
    vector<node>edge[MAXN];//MAXN是最大点数
    //加边
    cin>>bh>>tmp.to>>tmp.val;//读入边的起点、终点以及边权
    edge[bh].push(tmp);//给以bh号为起点的边,加一条
    //遍历
    for(int i=0;i<n;i++){
    	int len=edge[i].size();
    	for(int j=0;j<len;j++)
    		……
    }
    

    ③静态链表头插法存边(链式前向星):

    //定义:
    struct node {
        int to,val;//数据域.存储边指向的节点以及边权.
        int nxt;//指针域.假如目前这条边的起点为x,那么nxt则模拟了指针,保存下一个起点同样为x的边的编号
    } edge[MAXM];
    int bh=0;//初始化编号
    memset(head,-1,sizeof(head));//初始化head数组,用-1模拟NULL
    void add(int from,int to,int val) {//加边函数
        edge[++bh].to=to;    //存储边的数据
        edge[bh].val=val;
        edge[bh].nxt=head[from];    //头插法
        head[from]=bh;
    }
    for(int i=head[now]; i!=-1; i=edge[i].nxt){//遍历以now为起点的所有边
        int j=edge[i].to;
    	……
    }

    2. 最短路

    3. 拓扑排序

    4.

    四、数据结构

    1. 并查集:

    2. 最小生成树:

    3. 树状数组:

    基本功能:单点增减(无法将元素修改为某值,这需要线段树来干)、区间求和.
    时间复杂度:\(O_{(nlogn)}\),常数快于线段树
    ①单点增减、区间求和:单点增减直接调用updade函数,区间求和则是sum(right)-sum(left-1)

    //计算lowbit函数
    int lowbit(int x) {
        return x&-x;
    }
    //单点增减
    void update(int val,int bh) {
        int i=bh;
        while(i<=n) {
            c[i]+=val;
            i+=lowbit(i);
        }
    }
    //区间求和
    int sum(int i) {
        int tot=0;
        while(i>0) {
            tot+=c[i];
            i-=lowbit(i);
        }
        return tot;
    }

    ②区间增减、单点求值:树状数组本身与上面一样,只不过建树的时候更新的是差分数组,进行区间增减的时候,update(left,val)以及update(right+1,-val),求和的时候只需求差分数组的前缀和sum(x)
    ③区间增减、区间求和:

    4. ST表:

    5. 线段树:

    6.

    五、杂项

    1.对拍器:

    #include<iostream>
    #include<windows.h>
    using namespace std;
    int main() {
        int t=100;
        while(t) {
            t--;
            system("data.exe > data.txt");
            system("ac1.exe < data.txt > ac1.txt");
            system("t.exe < data.txt > t.txt");
            if(system("fc t.txt ac1.txt"))   break;
        }
        if(t==0) cout<<"no error"<<endl;
        else cout<<"error"<<endl;
        return 0;
    }
  • 相关阅读:
    移动硬盘和u盘的区别
    U盘文件系统格式
    WARN: Establishing SSL connection
    数据库基本操作命令
    PCM EQ DRC 音频处理
    那些年、那些歌、那些事
    编译与链接
    Flash芯片你都认识吗?
    ACM暑假集训第三周小结
    H
  • 原文地址:https://www.cnblogs.com/yige2019/p/15806272.html
Copyright © 2020-2023  润新知