ACM模板(从小白到ACMer的学习笔记)

写在开头:
2020年ICPC银川站,现场赛,第三题的字典树没能过,首站打铁,不过这一场也让我看到铜牌其实没有想象中的那么难。
2020年ICPC沈阳站,现场赛,封榜后过两题,铜首,I题原本需要黑题难度的知识推导,被队友找规律撕掉了,这一站之后也算成为了一名ACMer。
2021年CCPC桂林站,由本校举办,打星参加,题目质量很高,由于是打星,轻敌没带字典。第五题的key单词三个人都不认识,遗憾打铁,第四题的冒泡排序为之后的广州站做了铺垫–难以证明解法的真实性。
2021年CCPC广州站,作为2021年正式站的首战,铜尾,最后40分钟过的C题(二分答案+思维贪心),其实第四题也能写(打表斐波那契),和银牌差些时间。如果要讲讲这一站的题目,那只能说,没有金牌的实力就不要去想着证明,跟着感觉走。
2021年ICPC沈阳站.第一场icpc线上赛,打铁,过了四道题,H和L题的难度过大,加上B和J题过题太慢(J题最后一分钟过题),rank245,210枚铜牌。线上赛575个队,这对于罚时的要求很大。
2021年CCPC哈尔滨站,rk144,铁首,据说是因为有三个队没过题,牌子发到143.银牌题细节太多,最终没能t出来
2021年ICPC南京站,打铁,差两题,南京站可以说是诸神之战,原本以为卷不到铜牌区,实际上惨不忍睹。我校基地中原本冲金的队伍(哈尔滨站银牌rk1)也打铁了,这场也是2021年最后一场比赛,全程没有进过铜牌区,残酷。
大二上结束,退役与否还没这么快下结论,但是这一年半时间的算法学习,让我错过了很多风景,不过还好,我的内心仍然充满着热情和好奇,仍然有着踏入新领域的勇气。
也很庆幸,在大一纷繁的节奏中找到了对抗孤独的良药,焦虑,烦躁时,全身心投入的解一道题,de一个bug,便能感受到内心平和。
我们生长在最好的时代,我们生长在最坏的时代,我们能仰望星空,我们要脚踏实地。
2023/2/21 update:
大三上:完成ICPC,CCPC双银牌
2022年ICPC沈阳站 银牌 贡献了一道酒馆战棋的模拟题,比其他人更早发现这道题可做
2022年ccpc绵阳站 银牌 贡献了一道精度题,在队友都不出题的情况下,偷偷写题偷偷交题,一度c。

算法

markdown 语法网址
codeforce

报错

bool operator <(struct node &b)const
{
   
    return r-l<b.r-b.l;//等号可能会错
}

比赛模板

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il (i<<1)
#define ir (i<<1)+1
#define pb push_back
const int maxn=1e5+5;
inline char nc() {
   static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;}
inline void read(int &sum) {
   char ch=nc();sum=0;while(ch<'0') ch=nc();while(ch>='0') sum=(sum<<3)+(sum<<1)+(ch^48),ch=nc();}
ll qsm(ll a,ll b)
{
   
	ll base=a,ans=1;
	while(b>0)
	{
   
		if(b%2==1)ans=ans*base;
		base=base*base;
		b>>=1;
	}
	return ans;
}
ll gcd(ll a,ll b)
{
   
	return b==0?a:gcd(b,a%b);
}
void solve()
{
   
	
}
int main()
{
   
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)sovle();
	return 0;
}

STL

unordered_mapPostgraduate entrance examinatio

ceil()向上取整

floor()向下取整

__builtin_popcount()

用于一个数字的二进制中有多少个1.

bitset

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 1000000007;
const int MX = 1e3+1;
bitset<100*100*100+1>ans,t;
int main(){
   
    int n;scanf("%d",&n);
    ans[0]=1;
    while(n--){
   
        t.reset();
        int l,r;scanf("%d%d",&l,&r);
        while(l<=r){
   
            t|=ans<<(l*l);l++;
        }
        ans=t;
    }
    printf("%d",ans.count());
    return 0;
}

字符串操作

getline(cin,s);
to_string();
stoi/stol/stoll;

优先队列

priority_queue <int> q;
q.size();//返回q里元素个数
q.empty();//返回q是否为空,空则返回1,否则返回0
q.push(k);//在q的末尾插入k
q.pop();//删掉q的第一个元素
q.top();//返回q的第一个元素
q.back();//返回q的末尾元素
priority_queue<int> da;   //大根堆
priority_queue<int,vector<int>,greater<int> > xiao;  //小根堆

pair

震惊,map竟然是用pair 实现的。

#include <iostream>
#include <string>
#include <utility>
#include <map>

using namespace std;

int main() {
   	
	pair<string, string> p1("sc0301","小杨");	            // 方式一,创建一个pair名为p1
	pair<string, string> p2 = make_pair("sc0302", "小马");	// 方式二,make_pair函数返回一个用"sc0302"和 "小马"初始化的pair
	pair<string, string> p3("sc0303", "小王");
	pair<string, string> p4("sc0304", "小何");

	map<string, string> m1;                 // 创建一个空map
	map<string, string> m2{
    p1,p2,p3,p4 };  // 创建一个包含pair p1、p2、p3、p4的map
	map<string, string> m3{
    {
   "sc0301","小杨"},{
   "sc0302", "小马"},{
   "sc0303", "小王"},{
   "sc0304", "小何"} }; // 效果同上一句

	map<string, string>::iterator it1 = m2.begin();	 // 得到指向m2首元素的迭代器
	map<string, string>::iterator it2 = m2.end();    // 得到指向m2尾元素的下一个位置的迭代器
	pair<string, string> p11 = *it1;   // 得到m2的首元素{"sc0301","小杨"},这是一个pair
	string p1_ID = it1->first;         // 得到m2的首元素{"sc0301","小杨"}的fisrt成员,学号
	string p1_name = it1->second;	   // 得到m2的首元素{"sc0301","小杨"}的second成员,姓名


	for (auto p : m2) {
   
		cout << "学号:" << p.first << "; 姓名:" << p.second << endl;
	}

	m1.insert(p1);	                   // 在map中插入已有的pair
	m1.insert({
    "sc0302", "小马" });   // 插入键值对{ "sc0302", "小马" }
	m1.insert(pair<string, string> ("sc0303", "小王"));  // 创建一个无名pair对象,并插入到map中	
	m1.emplace(p1);			                             // 要插入的关键字已在容器中,emplace/insert什么都不做
	m1.emplace(pair<string, string>("sc0303", "小王"));  // 要插入的关键字已在容器中,emplace/insert什么都不做

	map<string, string>::iterator it = m2.find("sc0301");  // 查找关键字为"sc0301"的元素,返回一个迭代器
	if (it == m2.end()) {
            // 若"sc0301"不在容器中,则it等于尾后迭代器
		cout << "未找到!" << endl;
	}
	else {
   
		pair<string, string> result1 = *it;	// 找到了
	}

	int result2 = m2.count("sc0305");  // 查找关键字为"sc0301"的元素,返回关键字等于"sc0301"的元素数量
	if (result2==0) {
   
		cout << "未找到!" << endl;
	}
	else {
   
		cout << "找到了!" << endl;
	}
}

sort排序

struct cmp
     {
   
           bool operator()(int a,int b)
          {
   
               return dist[a]>dist[b];
          }
    };
friend <返回类型> <函数名> (<参数列表>);
friend bool operator<(const node &a,const node  &b)
{
   
	return a.x<b.x;
}
bool operator<(node &a)const
{
   
	return y<b.y;//y表示当前结构体的值
}
//**优先队列相反**

vector

vector<type> name;
a.clear(); //清空a中的元素
a.back(); //返回a的最后一个元素
a.front(); //返回a的第一个元素
vect.size();返回容器中元素的个数
vect.empty();判断容器是否为空
a.insert(a.begin()+1,5); //在a的第1个元素(从第0个算起)的位置插入数值5,
如a为1,2,3,4,插入元素后为1,5,2,3,4
vect.resize(num);重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
如果容器变短,则末尾超出容器长度的元素被删除。
vect.resize(num,elem);重新指定容器的长度为num,若容器变长,则以elem值填充新位置。
如果容器变短,则末尾超出容器长度的元素被删除。
vect.push_back(1);//在vector最后添加元素1
a.swap(b); //b为向量,将a中的元素和b中的元素进行整体性交换
vect.pop_back()//删除最后一个元素
vector<int> vect(a,a+10);//将数组a整体插入;
 sort(vect.begin(),vect.end());
for(int i=0;i<=b.size()-1;i++)

set

begin()     //返回set容器的第一个迭代器
end()    //返回set容器的最后一个迭代器
clear()    //删除set容器中的所有的元素
empty()  //判断set容器是否为空
max_size() //返回set容器可能包含的元素最大个数
size()    //返回当前set容器中的元素个数
rbegin   //返回的值和end()相同
rend()   //返回的值和rbegin()相同
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int a[maxn];
int main() {
   
	int n, q;
	cin >> n >> q;
	set<int>s;
	while (q--)
	{
   
		int op, id;
		cin >> op >> id;
		s.insert(0); s.insert(n);
		if (op == 1)s.insert(id);
		else
		{
   
			set<int>::iterator it;
			it = s.lower_bound(id);
			int len = *it - *(--it);
			cout << len << endl;
		}
	}
	return 0;
}

二分查找

upper_bound:
//在一个已排序的序列中[first, last),返回第一个大于val的元素所在的地址。如果未找到结果,则返回last;
lower_bound:
//在一个已排序的序列[first, last), 返回第一个大于等于val元素的地址,如未找到,则返回last;
binary_search:
//在一个已排序的序列[first, last)中, 判断val是否存在;

unique

3 3 2 5 2 3 -》 3 2 5 2 3 3

python黑科技

eval()函数

可以直接求字符串表达式的值注意:“^”转“**”;

s = input()
s1=""
for i in range(len(s)):
    if s[i]=="^" :
        s1=s1+"**"
    else :
        s1=s1+s[i]
print(eval(s1))

常用函数

最 da公约数

ll gcd(ll a,ll b){
   
    return b==0?a:gcd(b,a%b);
}
== __gcd()

快速幂

ll qsm(ll a,ll b)
{
   
    ll base=a,ans=1;
    while(b>0)
    {
   
        if(b%2==1)ans=ans*base;
        base=base*base;
        b>>=1;
    }
    return ans;
}

动态规划

数位dp

技巧 1:如果是从1->n,那么可以将区间问题转化为f(n)-f(m-1);

技巧2:利用数形结构来分析问题,注意last转移时的条件

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define ll long long
using namespace std;
const int maxn=20;
ll f[maxn][maxn];
ll K;
void init()
{
   
    for(int i=1; i<=9; i++) f[1][i]=1;
    for(int i=2; i<maxn; i++){
   
        for(int j=0;j<=9;j++)f[i][0]+=f[i-1][j];
        for(int j=1; j<=9; j++)
        {
   
            f[i][j]+=f[i-1][j];
            for(int k=j+K; k<=9; k++)
            {
   
                f[i][j]+=f[i-1][k];
            }
        }
    }
}

ll dp(ll n)
{
   
    if(!n) return 0;
    vector<int>nums;
    while(n) nums.push_back(n%10),n/=10;
    ll res=0;//方案数
    int last=0;
    for(int i=nums.size()-1; i>=0; i--)
    {
   
        int x=nums[i];//x为当前这位数
       // cout<<i<<" "<<x<<" "<<last<<" "<<res<<endl;
        if(i==nums.size()-1)
        {
   
            for(int j=0; j<x; j++) //要保障比下一位>=上一位,所以从last开始枚举,最多枚举到x,last为上一位,也即最高位,对下一位的枚举是有限制的
                res+=f[i+1][j];
            last=x;
            continue;                         //左端的节点有i+1个位数(因为第一位的下标是0)
        }
        if(x>last)
        {
   
            res+=f[i+1][last];
            for(int j=last+K; j<x; j++)res+=f[i+1][j];
            if(x>last&&x<last+K)break;
            last=x;

        }                                                        //如果当前这位数比上一位小,那么后面的都不成立了,直接break退出
        else if(x==last)x=last;
        else break;//如果能顺利到最后一个数说明树的最右边这一段的每一个数都是小于等于前一位数的,因而++
    }

    return res;
}

int main(void)
{
   
    ll l,r,L,R;
    cin>>l>>r>>K;
    init();
    cout<<dp(r)-dp(l-1)<<endl;
    //cout<<f[4][1]<<endl;
    return 0;
}

背包问题

背包问题一定是dp?

no!暴力搜索也能过背包问题,dp类似于记忆化搜索,如何有效利用已经被记录的信息是问题关键,如何保持信息的后续有效性也是关键。

#include<bits/stdc++.h>
using namespace std;
const int maxn=3e4;
const int maxm=26;
int v[maxn],w[maxn],n,m,res=0,dp[maxm][maxn];
int dfs(int i,int j)
{
   
	if(dp[i][j]!=-1)return dp[i][j];
	if(i==m)
	{
   
		return 0;
	}
	else if(j<v[i])res=dfs(i+1,j);
	else 
	{
   
		res=max(dfs(i+1,j),dfs(i+1,j-v[i])+v[i]*w[i]);
		dp[i][j]=res;
	}
	return res;
}
int main()
{
   
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=0;i<m;i++)cin>>v[i]>>w[i];
	memset(dp,-1,sizeof(dp));
	dfs(0,n);
	cout<<res<<endl;
	return 0;
}

01背包问题

一维数组需要逆序

二维需要对不操作的传递

bag[j]=maxv(bag[j],bag[j-w[i]]+v[i]);

完全背包问题

一维数组需要正序

maxValue[j] = max(maxValue[j], maxValue[j-w[i]] + v[i]);

多重背包问题

本质与01背包没有什么不同

分组背包问题

增加一维表示组别,保证只在这一组中选一个或者不选

数论

同余问题

定义:同余给定整数m,若用m去除两个整数a和b所得的余数相同,称a和b对模m同余,记作 a ≡   b ( m o d   m ) a\equiv \ b(mod\ m) a b(mod m)​。

定理1 a ≡ b ( m o d   m ) a\equiv b(mod\ m) ab(mod m)当且仅当 m ∣ ( a − b ) m|(a-b) m(ab)

定理2 a ≡ b ( m o d   m ) a\equiv b(mod\ m) ab(mod m)当且仅当存在k满足 a = b + k m a=b+km a=b+km

定理3 同余关系是等价关系

定理4 若a, b, c是整数,m是整数,且 a ≡ b ( m o d   m ) a\equiv b(mod\ m) ab(mod m),则:
a + c ≡ a + c ( m o d   m ) a − c ≡ a − c ( m o d   m ) a c ≡ b c ( m o d   m ) a+c\equiv a+c(mod\ m)\\ a-c\equiv a-c(mod\ m)\\ ac\equiv bc (mod \ m) a+ca+c(mod m)acac(mod m)acbc(mod m)
定理5 设a,b,c,d,为整数,m为正整数,若 a ≡ b ( m o d   m ) a\equiv b (mod\ m) ab(mod m) c ≡ d ( m o d   m ) c\equiv d(mod\ m) cd(mod m),则
a x + c y ≡ b x + d y ( m o d   m ) ( 即可加性 ) a c ≡ b d ( m o d   m ) ( 可乘性 ) a n ≡ b n ( m o d   m ) ( 可幂性 ) f ( a ) ≡ f ( b ) ( m o d   m ) ( f ( x ) 为任意整数多项式 ) ax+cy\equiv bx+dy(mod\ m)(即可加性)\\ ac\equiv bd(mod\ m)(可乘性)\\ a^n\equiv b^n(mod\ m)(可幂性)\\ f(a)\equiv f(b)(mod\ m)(f(x)为任意整数多项式) ax+cybx+dy(mod m)(即可加性)acbd(mod m)(可乘性)anbn(mod m)(可幂性)f(a)f(b)(mod m)(f(x)为任意整数多项式)
(ps:同余的性质十分稳定,具有线性。

定理6 设a,b,c,d为整数,m为正整数,则

  • a ≡ b ( m o d   m ) a\equiv b(mod\ m) ab(mod m),且d|m,则 a ≡ b ( m o d   d ) a\equiv b (mod\ d) ab(mod d)。(ps:当两数对m同余,对于m的因子也同余)
  • a ≡ b ( m o d   m ) a\equiv b(mod\ m) ab(mod m),则 g c d ( a , m ) = g c d ( b , m ) gcd(a,m)=gcd(b,m) gcd(a,m)=gcd(b,m)
  • a ≡ b ( m o d   m i ) , i = 1 , 2 , … , n a\equiv b (mod\ m_i),i=1,2,\dots,n ab(mod mi),i=1,2,,n成立,当且仅当 a ≡ b ( m o d [ m 1 , m 2 , … , m n ] ) a\equiv b (mod[m_1,m_2,\dots,m_n]) ab(mod[m1,m2,,mn]).

定理7 若 a c ≡ b c ( m o d   m ) , d = g c d ( c , m ) ac\equiv bc(mod \ m),d=gcd(c,m) acbc(mod m),d=gcd(c,m),则 a ≡ b ( m o d   m / d ) a\equiv b (mod \ m/d) ab(mod m/d)

扩展欧几里得

贝祖定理:如果a\b是整数,那么一定存在整数x,y使得 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)​有解

推论:如果 a x + b y = 1 ax+by=1 ax+by=1有解,那么 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1

int exgcd(int a, int b, int &x0, int &y0)
{
   
    if(!b)
    {
   
        x = 1, y = 0;
        return a;
    }
    int d = exgcd(b, a%b, y0, x0);
    y -= a/b*x;
    return d;
}
int main()
{
   
    int a, b;
    cin >> a >> b;
    int x0, y0;
    cout<<exgcd(a, b, x0, y0 )<<endl;
    cout<<(x%b+b)%b<<endl;
    return 0;
}

该函数的返回值为a和b的最大公因数d,其中x,y为其中一组解。

一次同余方程ax + by = c 有解的充要条件为 g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)c

g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)c是同余方程有 g c d ( a , n ) gcd(a,n) gcd(a,n)个解

x = x 0 + k ∗ b d x = x_0 +k*\frac{b}{d} x=x0+kdb

y = y 0 − k ∗ a d y = y_0 -k*\frac{a}{d} y=y0kda

欧拉函数

欧拉函数的定义

$\phi (n) $ 表示在1到n中,与n形成互质关系的数的个数。

欧拉函数的性质

  • 当n为质数时, ϕ ( n ) = n − 1 \phi(n)=n-1 ϕ(n)=n1

  • 欧拉函数是积性函数,但不是完全积性函数

    只有当 n = p 1 ∗ p 2 n=p_1*p_2 n=p1p2 时, ϕ ( n ) = ϕ ( p 1 ) ∗ ϕ ( p 2 ) \phi(n)=\phi(p_1)*\phi(p_2) ϕ(n)=ϕ(p1)ϕ(p2)

    ϕ ( p q ) = ϕ ( q ) ∗ ϕ ( p ) = ( p − 1 ) ( q − 1 ) \phi(pq)=\phi(q)*\phi(p)=(p-1)(q-1) ϕ(pq)=ϕ(q)ϕ(p)=(p1)(q1)(RSA算法应用)

  • 当n>2时, ϕ ( n ) \phi(n) ϕ(n)为偶数

当n为质数的k次幂时, ϕ ( n ) = p k − p k − 1 = ( p − 1 ) p k − 1 \phi(n)=p^k-p^{k-1}=(p-1)p^{k-1} ϕ(n)=pkpk1=(p1)pk1

证明,只用当数x为p的倍数时,两者才不互质,易得这类数的数量为 p k − 1 p^{k-1} pk1

通过以上的理论可以得到以下公式,
ϕ ( N ) = N ∗ ∏ i = 1 n ( 1 − 1 p i ) \phi(N) = N*\prod_{i=1}^{n}(1-\frac{1}{p_i}) ϕ(N)=Ni=1n(1pi1)
其中pi为质因子,即每个质因子只算一次。

o(n)的筛法筛出质数的同时求得其函数值

需要用到如下性质:

设p为质数

如果p为x的因数

那么 ϕ ( p ∗ x ) = p ∗ x ∗ ( 1 − 1 p 1 ) ∗ ( 1 − 1 p 2 ) ∗ . . . ( 1 − 1 p n ) ) = ϕ ( x ) ∗ p \phi(p*x)=p*x*(1-\frac{1}{p_1})*(1-\frac{1}{p_2})*...(1-\frac{1}{p_n}))=\phi(x)*p ϕ(px)=px(1p11)(1p21)...(1pn1))=ϕ(x)p

如果p不是x的因数,即px互质

那么 ϕ ( p ∗ x ) = ϕ ( p ) ∗ ϕ ( x ) = ϕ ( x ) ∗ ( p − 1 ) \phi(p*x)=\phi(p)*\phi(x)=\phi(x)*(p-1) ϕ(px)=ϕ(p)ϕ(x)=ϕ(x)(p1)

phi[1]=1;
for(int i=2;i<=maxn;i++)
	{
   
		if(!isprime[i])
		{
   
			prime[++cnt]=i;
			phi[i]=i-1;
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
几何\ 多边形 多边形切割 浮点函数 几何公式 面积 球面 三角形 三维几何 凸包(graham) 网格(pick) 圆 整数函数 注意 结构\ 并查集 并查集扩展(friend_enemy) 堆(binary) 堆(mapped) 矩形切割 线段树 线段树扩展 线段树应用 子段和 子阵和 其他\ 大数(整数类封装) 分数 矩阵 线性方程组(gauss) 日期 线性相关 数论\ 阶乘最后非零位 模线性方程(组) 质数表 质数随机判定(miller_rabin) 质因数分解 最大公约数欧拉函数 数值计算\ 定积分计算(Romberg) 多项式求根(牛顿法) 周期性方程(追赶法) 图论_NP搜索\ 最大团(n小于64) 最大团 图论_连通性\ 无向图关键边(dfs邻接阵形式) 无向图关键点(dfs邻接阵形式) 无向图块(bfs邻接阵形式) 无向图连通分支(bfs邻接阵形式) 无向图连通分支(dfs邻接阵形式) 有向图强连通分支(bfs邻接阵形式) 有向图强连通分支(dfs邻接阵形式) 有向图最小点基(邻接阵形式) 图论_匹配\ 二分图最大匹配(hungary邻接表形式) 二分图最大匹配(hungary邻接阵形式) 二分图最大匹配(hungary邻接表形式,邻接阵接口) 二分图最大匹配(hungary正向表形式) 二分图最佳匹配(kuhn_munkras邻接阵形式) 一般图最大匹配(邻接表形式) 一般图最大匹配(邻接阵形式) 一般图最大匹配(正向表形式) 一般图匹配(邻接表形式,邻接阵接口) 图论_网络流\ 上下界最大流(邻接阵形式) 上下界最小流(邻接阵形式) 上下界最大流(邻接表形式) 上下界最小流(邻接表形式) 最大流(邻接阵形式) 最大流(邻接表形式) 最大流(邻接表形式,邻接阵接口) 最大流无流量(邻接阵形式) 最小费用最大流(邻接阵形式) 图论_应用\ 欧拉回路(邻接阵形式) 前序表转化 树的优化算法 拓扑排序(邻接阵形式) 最佳边割集 最佳顶点割集 最小边割集 最小顶点割集 最小路径覆盖 图论_最短路径\ 最短路径(单源bellman_ford邻接阵形式) 最短路径(单源dijkstra邻接阵形式) 最短路径(单源dijkstra_bfs邻接表形式) 最短路径(单源dijkstra_bfs正向表形式) 最短路径(单源dijkstra+binary_heap邻接表形式) 最短路径(单源dijkstra+binary_heap正向表形式) 最短路径(单源dijkstra+mapped_heap邻接表形式) 最短路径(单源dijkstra+mapped_heap正向表形式) 最短路径(多源floyd_warshall邻接阵形式) 图论_支撑树\ 最小生成树(kruskal邻接表形式) 最小生成树(kruskal正向表形式) 最小生成树(prim邻接阵形式) 最小生成树(prim+binary_heap邻接表形式) 最小生成树(prim+binary_heap正向表形式) 最小生成树(prim+mapped_heap邻接表形式) 最小生成树(prim+mapped_heap正向表形式) 最小树形图(邻接阵形式) 应用\ joseph模拟 N皇后构造解 布尔母函数 第k元素 幻方构造 模式匹配(kmp) 逆序对数 字符串最小表示 最长公共单调子序列 最长子序列 最大子串匹配 最大子段和 最大子阵和 组合\ 排列组合生成 生成gray码 置换(polya) 字典序全排列 字典序组合 组合公式
上海交通大学ACM模板是指为了方便上海交通大学ACM队伍在参加ACM国内外比赛时,准备的一份包含常用算法模板和数据结构实现的文件。这份模板ACM队伍日常训练和比赛中必备的工具和参考资料。 ACM模板通常包括多个文件,每个文件对应一个具体的算法或数据结构,并提供了相应算法的思想、伪代码和具体实现。常见的内容包括但不限于:搜索算法、图论算法、动态规划、字符串处理、数论算法、几何算法、数据结构等。 ACM模板的好处主要有以下几点: 1. 提高编程效率:ACM模板中的算法和数据结构已经经过了优化和测试,可以直接拿来使用,避免了从零开始编写代码的时间和精力消耗。 2. 加深理解:通过研究ACM模板中的算法和数据结构实现,可以更深入地了解算法的原理和应用场景,从而提升对ACM竞赛中常见问题的解决能力。 3. 快速调试:ACM比赛通常时间紧迫,要求快速解决问题。ACM模板可以提供一些已经调试通过的代码,可以直接用于ACM比赛中,减少调试的时间。 4. 统一编程习惯:ACM模板中的代码通常是经过一段时间的磨合和调试得到的,可以作为一个学习的范本,帮助学习者养成良好的编程习惯。 上海交通大学ACM模板是上海交通大学ACM队伍根据自身经验和成果整理而成的,旨在为队员提供便利和帮助。同时,ACM模板也可以随着时间的推移进行更新和完善,以适应新的算法和数据结构的发展和变化。 总的来说,上海交通大学ACM模板ACM竞赛中的宝贵资料,对于提升队伍的竞赛实力和解决问题的效率具有重要意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值