ACM模板(快速幂、数论、图论)

这篇具有很好参考价值的文章主要介绍了ACM模板(快速幂、数论、图论)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

〇,全文说明、宏定义代码

一,代数

二,单例、快速幂、数论

二,test


〇,全文说明、宏定义代码

类里面和宏定义处都有接口注释,因为宏不体现具体参数,所以注释以类里面的为准。

所有代码放在一起是可以编译运行的,如果按照章来划分,除了最后一章是测试代码,其他任意一章都可以单独编译运行

 ACM模板(快速幂、数论、图论),算法

宏定义代码:

///(1)代数///
#define MinSumLen Algebra::minSumLen//最小距离问题,给出数轴上若干点,求出到任意点的总距离的最小值
#define EverSumLen Algebra::everSumLen//最小距离问题衍生问题,给出数轴上若干点,求出[low,high]段所有整点到所有点的总距离
// CloseInterval 略。闭区间的有序集合
#define GetLowBit Bits::getLowBit //二进制最低位
#define GetHighBit Bits::getHighBit//二进制最高位
#define IsPowerOf2 Bits::isPowerOf2 //是否是2的幂
#define GetBitLength Bits::getBitLength//二进制总位数
#define FgetNum1 Bits::getNum1 //二进制中1的个数
#define FgetNum0 Bits::getNum0 //二进制中0的个数,只算最高位1后面的0
#define GetReverseNum Bits::getReverseNum //二进制反转,01互换,仅限最高位1后面的位
// SemiGroup 略。半群

///(2.1)单例///
// SingleA 略。单例模板

///(2.2)快速乘法、幂、矩阵幂///
// 实现了泛埃及乘法,并泛化成了快速乘法、快速幂、矩阵快速幂。
// 我把接口都写成支持模p的,p的默认值是INT_MAX,需要模p的就给p传值就行。也支持嵌套,只需要扩展op函数即可。
#define MultiAdd Multi::multiAdd//快速乘法
#define MultiMulti Multi::multiMulti//快速幂
#define MultiMultiAdd Multi::multiMultiAdd//快速幂套快速乘法
#define MultiMatrix Multi::multiMatrix//矩阵快速幂

///(2.3)数论基础///
#define NumInRadix NumberTheory::numInRadix //一个数在d进制下的位数
#define IntToStr NumberTheory::intToStr //把整数转化为字符串,返回值是字符串长度
#define StrToInt NumberTheory::strToInt //把字符串转化为整数
#define IntRev NumberTheory::intRev//整数翻转,输入120,10,输出21
#define IsPrime NumberTheory::isPrime // 素数检测
#define GetHighNum NumberTheory::getHighNum //把3245分解成3*1000+245,出参a=3 b=1000 c=245
#define IsHas9 NumberTheory::isHas9 //一个十进制数里面有没有数字9
#define NumHas9 NumberTheory::numHas9 //1-n中有多少十进制数里面有数字9,n<10^9
#define IsPalindrome NumberTheory::isPalindrome //是否为回文数
#define Gcd NumberTheory::gcd //最大公约数
#define Lcm NumberTheory::lcm //最小公倍数

///(2.4)数论进阶///
#define IsPrime2 Sieve::GetSingleA().isPrime//判断n是不是素数
#define GetPrime Sieve::GetSingleA().getPrime//获取[1,n]内的所有素数
#define Fenjie Facs::fenjie //因式分解
#define Fenjie2 Facs::fenjie2 //因式分解
#define GetFacs Facs::getFacs //获取所有因子
#define GetMaxFacs Facs::getMaxFacs//获取最大因子
#define GetDivisors Facs::getDivisors//获取所有约数
#define IsSquareSum Facs::isSquareSum//判断是不是平方和
#define GetPhi Phi::getPhi//欧拉函数
#define GetFacsOfPhi Phi::getFacsOfPhi//计算phi(n)的所有因子facs,返回phi(n)
#define GetOrder Order::getOrder//求a mod n的阶
#define DiscreteLog BSGS::discreteLog//求离散对数a^x=b(mod p)
#define FactorialDegree Factorial::degree //求m!中素数p的次数
#define FactorialDegree2 Factorial::degree2 //求m!中n的次数
#define FactorialFactorization Factorial::factorization //求n!的因式分解
// ComNum 略

一,代数

class Algebra
{
public:
	//最小距离问题,给出数轴上若干点,求出到任意点的总距离的最小值
	template<typename T>
	static T minSumLen(vector<T>& v)
	{
		sort(v.begin(), v.end());
		T mid = (v[(v.size() - 1) / 2] + v[v.size() / 2]) / 2;
		T ans = 0;
		for (int i = 0; i < v.size(); i++)ans += abs(v[i] - mid);
		return ans;
	}
	//最小距离问题衍生问题,给出数轴上若干点,求出[low,high]段所有整点到所有点的总距离
	template<typename T>
	static vector<T> everSumLen(vector<T> v, int low, int high)
	{
		sort(v.begin(), v.end());
		vector<T>ans;
		int x = low, id = 0;
		T s = 0;
		for (auto vi : v)s += abs(vi - x), id += (vi < x);
		ans.push_back(s);
		for (x = low + 1; x <= high; x++) {
			s += id * 2 - int(v.size());
			while (id<v.size() && x>v[id]) {
				s += 1 + abs(v[id] - x) - abs(v[id] - x + 1);
				id++;
			}
			ans.push_back(s);
		}
		return ans;
	}
};

//闭区间,type=0表示整点区间,type=1表示整段区间,type=2表示浮点数区间
template<int type, typename T = int> //type=2 T=float   type<2 T=int
struct CloseIval
{
	T low, high;
	CloseIval() {}
	CloseIval(T low, T high) :low{ low }, high{ high }
	{
		gap = (type ? 0 : 1);
	}
	bool operator<(const CloseIval& ci)const //按照左端点进行排序
	{
		return low < ci.low;
	}
	bool canMerge(const CloseIval& ci) const
	{
		return ci.low <= high + gap && ci.high >= low - gap;
	}
	void merge(const CloseIval& ci)  //canMerge==true才调用merge
	{
		low = min(low, ci.low), high = max(high, ci.high);
	}
	bool canDel(const CloseIval& ci) const //对于浮点数区间,减法定义不严谨,慎用
	{
		return canMerge(ci);
	}
	vector<CloseIval> del(const CloseIval& ci)const  //canDel==true才调用del
	{
		vector<CloseIval> ans;
		if (low < ci.low)ans.push_back({ low,ci.low - gap });
		if (high > ci.high)ans.push_back({ ci.high + gap,high });
		return ans;//0-2个
	}
private:
	T gap;
};
//闭区间的有序集合,type=0表示整点区间,type=1表示整段区间,type=2表示浮点数区间
template<int type, typename T = int> //type=2 T=float   type<2 T=int
class CloseInterval {
public:
	using Ival = CloseIval<type, T>;
	vector<Ival>allCi;//所有区间,一直保持排序
public:
	//新增区间,尾部插入效率是O(log n),中间插入效率是O(n)
	void push(Ival ci)
	{
  		auto it = lower_bound(allCi.begin(), allCi.end(), ci);
		auto it2 = it;
		bool canMergeFlag = it!= allCi.end() && it->canMerge(ci);
		bool canMergeFlag2 = false;
		if (it != allCi.begin()) {
			it--; //可能可以merge的第一个区间
			canMergeFlag2 = it->canMerge(ci);
		}
		if (!canMergeFlag && !canMergeFlag2) {
			allCi.insert(it2, ci);
			return;
		}
		if (!canMergeFlag2)it = it2;
		//此时it是可以merge的第一个区间
		it->merge(ci);
		it2 = it;
		it2++;
		for (; it2 != allCi.end(); it2++) {
			if (!it->canMerge(*it2))break;
			it->merge(*it2); //往后把所有能merge的都merge到第一个区间
		}
		it++;
		while (it2 != allCi.end())*it++ = *it2++; //剩下没merge的往前平移
		allCi.resize(it - allCi.begin());
	}
	//减掉区间,效率是O(n)
	void del(Ival ci)
	{
		vector<Ival>ans;
		for (auto any : allCi) {
			if (any.canMerge(ci)) {
				auto tmp = any.del(ci);
				for (auto t : tmp)ans.push_back(t);
			}
			else ans.push_back(any);
		}
		allCi = ans;
	}
};

//二进制运算,n>0
class Bits {
public:
	//二进制最低位
	static inline long long getLowBit(long long n) {
		return n & (-n);
	}
	//二进制最高位
	static inline long long getHighBit(long long n) {
		while (n != getLowBit(n)) n ^= getLowBit(n);
		return n;
	}
	//是否是2的幂
	static inline bool isPowerOf2(long long n) {
		return n == getLowBit(n);
	}
	//二进制总位数
	static inline int getBitLength(long long n) {
		int ans = 0;
		while (n)
		{
			n >>= 1;
			ans++;
		}
		return ans;
	}
	//二进制中1的个数
	static inline int getNum1(long long n) {
		int ans = 0;
		while (n)
		{
			n ^= getLowBit(n);
			ans++;
		}
		return ans;
	}
	//二进制中0的个数,只算最高位1后面的0
	static inline int getNum0(long long n) {
		return getBitLength(n) - getNum1(n);
	}
	//二进制反转,01互换,仅限最高位1后面的位
	static inline long long getReverseNum(long long n) {
		long long a = 1, len = getBitLength(n);
		return (a << len) - 1 ^ n;
	}
};
//半群
class SemiGroup
{
public:
	//枚举只去掉1个数(v.size()>1),剩下的数做p累积运算的结果
	template<typename T, typename Tfunc>
	static vector<T> allExceptOne(vector<T>& v, Tfunc p) {
		vector<T>left(v.size() - 1), right(v.size() - 1);
		T x = v[0];
		for (int i = 1; i < v.size(); i++)left[i - 1] = x, x = p(x, v[i]);
		x = v.back();
		for (int i = int(v.size()) - 2; i >= 0; i--)right[i] = x, x = p(v[i], x);
		vector<T>ans(1, right[0]);
		for (int i = 0; i < left.size() - 1; i++)ans.push_back(p(left[i], right[i + 1]));
		ans.push_back(left.back());
		return ans;
	}
};

二,单例、快速幂、数论


template<typename T>
class SingleA {
public:
	static T& GetSingleA() {
		static T s;
		return s;
	}
protected:
	SingleA(const SingleA&) = delete;
	SingleA(SingleA&&) = delete;
	SingleA& operator=(const SingleA&) = delete;
	SingleA& operator=(SingleA&&) = delete;
	SingleA() = default;
	~SingleA() = default;
};
class Multi
{
public:
	template<typename N>
	static long long multiAdd(long long a, N n, int p = INT_MAX)//快速乘法,n>0
	{
		return aijiMulti(a, n, p, opAdd<long long>);
	}
	template<typename N>
	static long long multiMulti(long long a, N n, int p = INT_MAX)//快速幂,n>0
	{
		return aijiMulti(a, n, p, opMulti<long long>);
	}
	template<typename N>
	static long long multiMultiAdd(long long a, N n, int p = INT_MAX)//快速幂套快速乘法,n>0
	{
		return aijiMulti(a, n, p, opMultiAdd<long long>);
	}
	template<typename A, typename N>
	static vector<vector<A>> multiMatrix(vector<vector<A>> a, N n, int p = INT_MAX)//矩阵快速幂,n>0
	{
		return aijiMulti(a, n, p, opMatrixMulti<A>);
	}
protected:
	template<typename A>
	static inline A opAdd(A x, A y, int p)
	{
		return (x + y) % p;
	}
	template<typename A>
	static inline A opMulti(A x, A y, int p)
	{
		return (x * y) % p;
	}
	template<typename A>
	static inline A opMultiAdd(A x, A y, int p)
	{
		return aijiMulti(x, y, p, opAdd<A>);
	}
	template<typename A>
	static inline vector<vector<A>> opMatrixMulti(vector<vector<A>> x, vector<vector<A>> y, int p)
	{
		vector<vector<A>> ans = x;
		for (int i = 0; i < ans.size(); i++) {
			for (int j = 0; j < ans.size(); j++) {
				ans[i][j] = 0;
				for (int k = 0; k < ans.size(); k++)ans[i][j] += (x[i][k] * y[k][j]) % p;
			}
		}
		return ans;
	}
	template<typename A, typename N>
	static inline A aijiMulti(A a, N n, int p, A(*pfunc)(A, A, int))
	{
		if (n <= 1)return a;
		A ans = aijiMulti<A, N>(a, n / 2, p, pfunc);
		ans = pfunc(ans, ans, p);
		if (n % 2)ans = pfunc(ans, a, p);
		return ans;
	}
};
class NumberTheory
{
public:
	//一个数在d进制下的位数
	static int numInRadix(long long m, int d)
	{
		if (m == 0)return 1;
		int s = 0;
		while (m)
		{
			s++;
			m /= d;
		}
		return s;
	}
	//把整数转化为字符串, 出参str不用初始化,返回值是字符串长度
	static int intToStr(long long num, unsigned radix, char*& str)
	{
		int len = numInRadix(num, radix);
		str = new char[len + 2];
		char index[] = "0123456789ABCDEF";
		int k = 0;
		if (num < 0)str[0] = '-', k = 1;
		num = abs(num);
		for (int i = len - 1 + k; i >= k; i--)
		{
			str[i] = index[num % radix], num /= radix;
		}
		str[len + k] = '\0';
		return len + k;
	}
	//把字符串转化为整数
	static long long strToInt(const char* nptr, int radix) //库函数atoi只支持十进制
	{
		int k = 0;
		if (*nptr == '-')k = 1, nptr++;
		long long ans = 0;
		while (*nptr) {
			int x = (*nptr >= '0' && *nptr <= '9') ? *nptr - '0' : *nptr - 'A';
			ans = ans * radix + x, nptr++;
		}
		return k ? -ans : ans;
	}
	// 素数检测
	static bool isPrime(int n)
	{
		if (n == 2)return true;
		if (n % 2 == 0)return false;
		for (int i = 3; i * i <= n; i += 2) if (n % i == 0)return false;
		return true;
	}
	//把3245分解成3*1000+245,出参a=3 b=1000 c=245
	static void getHighNum(int n, int& a, int& b, int& c)
	{
		int m = n;
		b = 1;
		m /= 10;
		while (m)b *= 10, m /= 10;
		a = n / b, c = n % b;
	}
	//一个十进制数里面有没有数字9
	static bool isHas9(int n)
	{
		while (n) {
			if (n % 10 == 9)return true;
			n /= 10;
		}
		return false;
	}
	//1-n中有多少十进制数里面有数字9,n<10^9
	static int numHas9(int n)
	{
		if (n <= 1)return 0;
		int num[10] = { 0,1,19,271,3439,40951,468559,5217031,56953279,612579511 };
		int a, b, c;
		getHighNum(n, a, b, c);
		int d = 0;
		while (b > 1)d++, b /= 10;
		return a * num[d] + (a == 9 ? c + 1 : isHas9(c));
	}
	//是否为回文数
	static bool isPalindrome(int x)
	{
		if (x < 0)return false;
		vector<int>num;
		while (x)
		{
			num.insert(num.end(), x % 10);
			x /= 10;
		}
		int len = num.size();
		for (int i = 0, j = len - 1; i < j; i++, j--)
		{
			if (num[i] - num[j])return false;
		}
		return true;
	}
	//最大公约数
	static long long gcd(long long a, long long b)
	{
		if (b == 0)return a;
		return gcd(b, a % b);
	}
	//最小公倍数
	static long long lcm(long long a, long long b)
	{
		a /= gcd(a, b);
		if (a > LLONG_MAX / b)return 0;
		return a * b;
	}
};
class Sieve : public SingleA<Sieve>
{
	static const int N = 200000;
	friend class SingleA<Sieve>;
public:
	bool isPrime(int n)//判断n是不是素数
	{
		if (n < 2)return false;
		calPrime(n);
		return prime[n];
	}
	vector<int> getPrime(int n)//获取[1,n]内的所有素数,如果曾经传过更大的N,则返回[1,N]内的所有素数
	{
		if (n < 2)return vector<int>{};
		calPrime(n);
		return vPrime;
	}
private:
	Sieve() {
		prime[0] = prime[1] = 0, prime[2] = 1;
		flag = 2;
		for (int i = 3; i < N; i += 2)prime[i] = 1;
		vPrime.reserve(N / 5);
		vPrime.push_back(2);
	}
	void calPrime(int n)//判断[1,n]内的素数,n<N
	{
		if (flag >= n)return;
		for (int i = flag + 1 + flag % 2; i <= n; i += 2)if (prime[i])
		{
			vPrime.push_back(i);
			for (int j = i + i; j < N; j += i)prime[j] = 0;
		}
		flag = n;
	}
private:
	int flag;
	int prime[N];
	vector<int>vPrime;
};
class Facs:public Sieve
{
public:
	//因式分解,把12分解成{<2,2>,<3,1>}
	static vector<pair<int, int>> fenjie(int n)
	{
		vector<pair<int, int>> vp;
		for (auto i : GetSingleA().getPrime(sqrt(n + 1)))
		{
			if (n % i)continue;
			int k = 0;
			while (n % i == 0)n /= i, k++;
			vp.push_back({ i, k });
		}
		if (n > 1) vp.push_back({ n, 1 });
		return vp;
	}
	//积性分解,即单素数幂分解,把12分解成{4,3}
	static vector<int> fenjie2(int n)
	{
		vector<pair<int, int>> vp = fenjie(n);
		vector<int>ans;
		for (auto vi : vp) {
			int s = 1;
			while (vi.second--)s *= vi.first;
			ans.push_back(s);
		}
		return ans;
	}
	//获取所有因子
	static vector<int> getFacs(int n)
	{
		vector<pair<int, int>> vp = fenjie(n);
		vector<int>ans;
		for (auto vi : vp)ans.push_back(vi.first);
		return ans;
	}
	//获取最大因子
	static int getMaxFacs(int n)
	{
		vector<int> v = getFacs(n);
		return *v.rbegin();
	}
	//获取所有约数
	static vector<int> getDivisors(int n)
	{
		vector<pair<int, int>>v = fenjie(n);
		vector<int>ans, ans2;
		ans.push_back(1);
		if (n <= 1)return ans;
		for (auto vi : v) {
			vector<int>ans2(ans.size() * (vi.second + 1));
			copy(ans.begin(), ans.end(), ans2.begin());
			for (int i = ans.size(); i < ans2.size(); i++) ans2[i] = ans2[i - ans.size()] * vi.first;
			ans = ans2;
		}
		sort(ans.begin(), ans.end());
		return ans;
	}
	static int findNear(int x, int a) // 1<a<x
	{
		auto v = getDivisors(x);
		for (int i = 0; i < v.size(); i++) {
			if (v[i + 1] <= a)continue;
			if (v[i] + v[i + 1] - a * 2 > 0)return v[i];
			return v[i + 1];
		}
		return 0;
	}
	//判断是不是平方和
	static bool isSquareSum(int n)
	{
		vector<pair<int, int>> vp = fenjie(n);
		for (auto &p : vp) {
			if (p.first % 4 == 3 && p.second % 2 == 1)return false;
		}
		return true;
	}
};
class Phi :public Facs
{
public:
	//欧拉函数
	static int getPhi(int n)
	{
		static map<int, int>m;
		if (m[n])return m[n];
		return m[n] = getPhiWithFacs(n, getFacs(n));
	}
	//计算phi(n)的所有因子facs,返回phi(n)
	static int getFacsOfPhi(int n, vector<int>& facs)
	{
		vector<pair<int, int>> vp = fenjie(n);
		vector<int>v;
		set<int>facSet;
		for (auto vi : vp) {
			v.push_back(vi.first);
			if (vi.second > 1)facSet.insert(vi.first);
			for (auto x : getFacs(vi.first - 1))facSet.insert(x);
		}
		for (auto x : facSet)facs.push_back(x);
		return getPhiWithFacs(n, v);
	}
private:
	//已知n的所有因子,求欧拉函数
	static int getPhiWithFacs(int n, const vector<int>& v)
	{
		int ans = n;
		for (auto vi : v)ans = ans / vi * (vi - 1);
		return ans;
	}
};
class Order :public Phi, public NumberTheory, public Multi
{
public:
	//求a mod n的阶,-1表示不存在
	static int getOrder(int a, int n)
	{
		if (gcd(a, n) != 1)return -1;
		vector<int> facsOfPhi;
		int thephi = getFacsOfPhi(n, facsOfPhi);
		return getOrder(a, n, thephi, facsOfPhi);
	}
private:
	//求a mod n的阶,一定是upPie的约数
	static int getOrder(int a, int n, int upPie, vector<int>& facsOfPhi)
	{
		for (auto vi : facsOfPhi) {
			while (upPie % vi == 0 && multiMulti(a, upPie / vi, n) % n == 1)upPie /= vi;
		}
		return upPie;
	}
};
class BSGS :public Order //求离散对数a^x=b(mod p)
{
public:
	static long long discreteLog(long long a, long long b, int p)
	{
		a = (a % p + p) % p, b = (b % p + p) % p;
		if (a == 0)return (b == 0) ? 1 : -1;
		int maxLog = getOrder(a, p);
		long long m = (long long)sqrt(double(maxLog));
		long long c = multiMulti(a, p - 1 - m, p);
		set<long long>s;
		map<long long, long long>ma;
		long long x = 1;
		for (int j = 0; j < m; j++) {
			if (j > 0 && x == 1)break;
			s.insert(x);
			ma[x] = j;
			x = x * a % p;
		}
		for (int i = 0; i <= maxLog / m; i++) {
			if (s.find(b) != s.end()) {
				return i * m + ma[b];
			}
			b = b * c % p;
		}
		return -1;
	}
};

class Factorial:public Facs
{
public:
	static inline int degree(int m, int p)//求m!中素数p的次数
	{
		int ans = 0;
		while (m)ans += m / p, m /= p;
		return ans;
	}
	static inline int degree2(int m, int n)//求m!中n的次数
	{
		vector<pair<int, int>> vp = fenjie(n);
		int ans = degree(m, vp[0].first) / vp[0].second;
		for (int i = 1; i < vp.size(); i++)ans = min(ans, degree(m, vp[i].first) / vp[i].second);
		return ans;
	}
	static vector<pair<int, int>> factorization(int n) //求n!的因式分解
	{
		vector<pair<int, int>> vp;
		for (auto i : GetSingleA().getPrime(n)) {
			if (i > n)break;
			vp.push_back({ i, degree(n,i) });
		}
		return vp;
	}
};
class ComNum :public Factorial
{
public:
	static vector<pair<int, int>> fenjie(int n, int k) //组合数C(n,k)的因式分解
	{
		auto ps = Sieve::GetSingleA().getPrime(n + k);
		vector<pair<int, int>> ans;
		for (auto p : ps) {
			int mi = degree(n, p) - degree(k, p) - degree(n - k, p);
			if (mi)ans.push_back(make_pair(p, mi));
		}
		return ans;
	}
	static int getValue(int n, int k, int p = INT_MAX) //组合数C(n,k)%p
	{
		vector<pair<int, int>> v = fenjie(n, k);
		long long ans = 1;
		for (auto par : v)
		{
			int mi = par.second;
			while (mi--)ans = ans * par.first%p;
		}
		return ans;
	}
};

三,test

测试代码还比较拉垮,先测试编译问题。文章来源地址https://www.toymoban.com/news/detail-546562.html

template<typename T>
static bool isSame(const vector<T>& v1, const vector<T>& v2)
{
	if (v1.size() - v2.size())return false;
	for (int i = 0; i < v1.size(); i++)if (v1[i] != v2[i])return false;
	return true;
}
#define EXPECT_VEC_EQ(a,b) if(!isSame((a),(b))){cout<<"ERROR!!!!!!!!!\n";return false;}
#define EXPECT_EQ(a,b) if(a!=b){cout<<"ERROR!!!!!!!!!\n";return false;}

bool testAlgebra()//待完善
{
	vector<int>v{ 1,3,6 };
	auto ans = EverSumLen(v, 0, 5);//{10,7,6,5,6,7}
	vector<double>v2{ 1, 3, 3.3, 6 };
	auto ans2 = EverSumLen(v2, 1, 4);//{9.3, 7.3, 5.3, 6.7}
	return true;
}
bool testMinExcept()//待完善
{
	vector<int>v;
	MinExcept{ v };
	return true;
}
bool testCloseInterval()//待完善
{
	CloseIval<true>{1, 2};
	CloseInterval<true>{};
	return true;
}
bool test1()
{
	return testAlgebra() && testMinExcept() && testCloseInterval();
}

bool testMulti()//待完善
{
	EXPECT_EQ(MultiMulti(2, 10), 1024);
	return true;
}
bool testNumberTheory()//待完善
{
	NumberTheory{};
	return true;
}
bool testSieve()//待完善
{
	Sieve::GetSingleA();
	return true;
}
bool testFacs()//待完善
{
	Facs::fenjie(100);
	return true;
}
bool testPhi()//待完善
{
	Phi::getPhi(100);
	return true;
}
bool testOrder()//待完善
{
	Order::getOrder(10, 100);
	return true;
}
bool testBSGS()//待完善
{
	BSGS::discreteLog(2, 1, 97);
	return true;
}
bool testFactorial()//待完善
{
	return true;
}
bool testComNum()//待完善
{
	return true;
}
bool test2()
{
	return testMulti() && testNumberTheory() && testSieve() && testFacs() && testPhi() && testOrder() && testBSGS()
		&& testFactorial() && testComNum();
}

int main()
{
	if (test1() && test2())cout << "test succ!";
	return 0;
}

到了这里,关于ACM模板(快速幂、数论、图论)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 搜索+图论+数论

    😋 时间复杂度: 邻接矩阵:O(v^2) (v是点数) 邻接表: O(v+m) (v是点数,m是边数) 😋 数字排列 😋 n皇后问题(优化版) 😋 n皇后问题(初阶版) 😋 时间复杂度 邻接矩阵:O(v^2) (v是点数) 邻接表: O(v+m) (v是点数,m是边数) 😋 迷宫最短路问题 😎 树的重心问题 参

    2024年04月27日
    浏览(16)
  • 算法模板(3):搜索(3):图论提高

    (1)朴素版prim算法( O ( n 2 ) O(n ^ 2) O ( n 2 ) ) 适用范围:稠密图 易错:注意有向图还是无向图;注意有没有重边和负权边。 从一个集合向外一个一个扩展,最开始只有 1 1 1 这个结点,然后把元素一个一个加进来,每次加的元素就是离这个集合距离最小的元素,可以设为

    2024年02月09日
    浏览(33)
  • 算法模板(3):搜索(4):高等图论

    相关概念 强连通分量:Strongly Connected Component (SCC). 对于一个有向图顶点的子集 S S S ,如果在 S S S 内任取两个顶点 u u u 和 v v v ,都能找到一条 u u u 到 v v v 的路径,那么称 S S S 是强连通的。 如果在强连通的顶点集合 S S S 中加入其他任意顶点集合后,它都不再是强连通的,那

    2024年02月08日
    浏览(35)
  • 【算法入门&图论】【模板】拓扑排序|【模板】单源最短路2 |最小生成树

    ✅作者简介:热爱后端语言的大学生,CSDN内容合伙人 ✨精品专栏:C++面向对象 🔥系列专栏:算法百炼成神 本专栏收录的均为牛客网的算法题目,内含链表、双指针、递归、动态规划、基本数据结构等算法思想的具体运用。牛客网不仅有大量的经典算法题目,也有大厂的面

    2024年02月03日
    浏览(34)
  • 【C++算法模板】图论-拓扑排序,超详细注释带例题

    推荐视频链接:D01 拓扑排序 给定一张 有向无环图 ,排出所有顶点的一个序列 A A A 满足:对于图中的每条有向边 ( x , y ) (x,y) ( x , y ) , x x x 在 A A A 中都出现在 y y y 之前,则称 A A A 是该图的顶点的一个拓扑序 拓扑排序 可以判断有向图中是否有环,可以生成拓扑序列 对于下

    2024年04月15日
    浏览(32)
  • ⌈算法进阶⌋图论::并查集——快速理解到熟练运用

    目录  一、原理 1. 初始化Init   2. 查询 find  3. 合并 union 二、代码模板 三、练习 1、  990.等式方程的可满足性🟢 2、  1061. 按字典序排列最小的等效字符串🟢 3、721.账户合并 🟡 4、  839.相似字符串组🟡 5、  2812.找出最安全路径 🔴 并查集主要运用与求一些 不相交且有关

    2024年02月13日
    浏览(25)
  • 【算法每日一练]-图论(保姆级教程篇14 )#会议(模板题) #医院设置 #虫洞(模板题) #无序字母对 #旅行计划 #最优贸易

    目录 今日知识点: 求数的重心先dfs出d[1]和cnt[i],然后从1进行dp求解所有d[i] 两两点配对的建图方式,检查是否有环 无向图欧拉路径+路径输出 topo+dp求以i为终点的游览城市数 建立分层图转化盈利问题成求最长路 会议(模板题) 医院设置  虫洞(模版题) 无序字母对  旅行

    2024年02月02日
    浏览(36)
  • 【算法每日一练]-图论(保姆级教程篇15 )#会议(模板题) #医院设置 #虫洞(模板题) #无序字母对 #旅行计划 #最优贸易

    目录 今日知识点: 求数的重心先dfs出d[1]和cnt[i],然后从1进行dp求解所有d[i] 两两点配对的建图方式,检查是否有环 无向图欧拉路径+路径输出 topo+dp求以i为终点的游览城市数 建立分层图转化盈利问题成求最长路 会议(模板题) 医院设置  虫洞(模版题) 无序字母对  旅行

    2024年01月21日
    浏览(35)
  • 二、搜索与图论6:Dijkstra 模板题+算法模板(Dijkstra求最短路 I, Dijkstra求最短路 II,1003 Emergency)

    朴素dijkstra算法 对应模板题:Dijkstra求最短路 I 时间复杂是 O(n^2+m):n 表示点数,m 表示边数 堆优化版dijkstra 对应模板题:Dijkstra求最短路 II 时间复杂度 O(mlogn):n 表示点数,m 表示边数 树是一种特殊的图 ,与图的存储方式相同。 对于无向图中的边ab,存储两条有向边a-b, b-a。

    2024年02月14日
    浏览(27)
  • ⌈算法进阶⌋图论::拓扑排序(Topological Sorting)——快速理解到熟练运用

    目录  一、原理 1. 引例:207.课程表  2. 应用场景 3. 代码思路 二、代码模板 三、练习 1、210.课程表Ⅱ🟢 2、2392.给定条件下构造举证🟡 3、310.最小高度树🟡 4、 2603.收集树中金币 🔴 1. 引例:207.课程表 就如大学课程安排一样,如果要学习数据结构与算法、机器学习这类课程

    2024年02月11日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包