数学


vector排序

vector<int >an;
sort(an.begin(),an.end());//从小到大排列;

更相减损术

适用于求:gcd_sub(pow(a,b),pow(a,c))=pow(a,gcd(b,c))

ll gcd_sub(ll a, ll b) {
	if (a < b)
		swap(a, b);
	if (b == 1)
	return a;
	return gcd_sub(b, a / b);
}

三分法

对于求一个只包含一个波峰或者波谷函数的最值,通过求两个三分点进行比较,更接近目标的是好点,否则是坏点,坏点的那一边往里缩,因为目标和好点一定在坏点的一侧,坏点的那边就不包含最优解了

double left = 0, right = 1000;
		double ans = 0x3f3f3f3f;
		while (fabs(right - left) > lp) {
			double ll = left + (right - left) / 3;
			double rr = right - (right - left) / 3;
			double rrans = 0;
			double llans = 0;
			for (int i = 1; i <= n; i++) {
				rrans = max(rrans, a[i] * rr * rr + b[i] * rr + c[i]);//求解函数值
				llans = max(llans, a[i] * ll * ll + b[i] * ll + c[i]);//求解函数值
			}
			ans = min(rrans, llans);
			if (rrans < llans)//注意这里的更小值是好点,所以rr是好点,ll那边就要缩
				left = ll;
			else
				right = rr;
		}

保序离散化

提前将所有要用到的下标存进alls里面(vector),队alls进行排序+去重,对于要用到的下标根据find函数去寻找,注意在返回时+1,相当于将这些下标映射在1~alls.size()。

sort(alls.begin(), alls.end());//排序
alls.erase(unique(alls.begin(), alls.end()), alls.end());//去重,unique函数返回不重复序列的后一个指针。
int find(int a) {
	int l = 0, r = alls.size() - 1;
	while (l < r) {
		int mid = r + l >> 1;
		if (alls[mid] < a)
			l = mid + 1;
		else
			r = mid;
	}
	return l + 1;
}

非保序离散化

用unordered_map和递增的idx赋予每一个下标一个独特的值,代码量简单,与alls区别是寻找和离散化过程结合在一起。

int idx=0;
unordered_map<int,int> res;
res.clear();
idx=0;
int find(int a) {
	if (res.count(a) == 0)
		res[a] = ++idx;
	return res[a];
}

字符串操作:


string str1("hello");
cout << str1 << endl;//hello
string str2("hello",2);//指定字符串的前2个字符
cout << str2 << endl;//he
string str3(str1, 2);//从下标2开始的字符的拷贝
cout << str3 << endl;//llo
string str4(str1, 2,2);//从下标2开始的2个字符的拷贝
cout << str4 << endl;//ll

约数个数

给定 n个正整数 ai,请你输出这些数的乘积的约数个数,答案对 109+7取模
假设k=a1^p1a2^p2a3^p3
那么约数个数为(p1+1)(p2+1)(p3+1)

约数之和

假设k=a1^p1a2^p2a3^p3
约数和为(pow(a1,0)+pow(a1,1)+….pow(a1,p1)(pow(a2,0)+pow(a2,1)+….pow(a2,p2))(pow(a3,0)+pow(a3,1)+….pow(a3,p3))

欧几里得

返回的是a和b的最大公约数

int gcd(int a, int b)
{
	return b ? gcd(b, a % b) : a;
}

拓展欧几里得

适用于ax+by=gcd(a,b) 通解为x0+z*(b/p) y0-z*(a/p) z为任意整数 如果右边不是gcd(a,b) 则必须整除gcd(a,b)才有解,并且x0和y0要相应的改变

int exgcd(int a, int b, int& x, int& y)
{
	if (!b)
	{
		x = 1;
		y = 0;
		return;
	}
	exgcd(b, a % b, y, x);
	y = y - a / b * x;
}

筛质数(n):

bool st[100001000];
vector<int> res;
void get_prime(int n)
{
	for (int a = 2; a <= n; a++)
	{
		if (!st[a])
		{
			res.push_back(a);
		}
		for (int j = 0; res[j]*a <= n; j++)
		{
			st[a * res[j]] = true;
			if (a % res[j] == 0)
				break;
		}
	}
}

分解质因数(logn):

unordered_map<int, int> res;
void help(int a)
{
	for (int i = 2; i <= sqrt(a); i++)
	{
			while (a % i == 0)
			{
				res[i]++;
				a = a / i;
			}
	}
	if (a > 1)
		res[a]++;
}

秦九韶算法

针对a0pow(p,0)+a1pow(p,1)+a2pow(p,2)+….anpow(p,n);

long long int o=an;
		for(int i=n-1;i>=0;i--)
			o = (o * p + a[i]) % mod;

矩阵快速幂

(要理解本质,ab的矩阵与bc的矩阵相乘结果为a*c的数组,遍历顺序是a到c到b)

void mul(ll an[][6], ll bn[][6],ll cn[][6])
{
	ll temp[6][6];
	memset(temp, 0, sizeof(temp));
	for (int i = 0; i < 6; i++)
	{
		for (int j = 0; j < 6; j++)
		{
			for (int z = 0; z < 6; z++)
			{
				temp[i][j] =(temp[i][j]+ an[i][z] * bn[z][j] % N)%N;
			}
		}
	}
	memcpy(cn, temp, sizeof(temp));
}

void quickmi(ll an[6][6], ll p)
{
	ll res[6][6];
	memset(res, 0, sizeof(res));
	for (int i = 0; i < 6; i++)
	{
		res[i][i] = 1;
	}
	while (p > 1)
	{
		if (p & 1)
		{
			mul(res, an,res);
			p--;
		}
		p = p / 2;
		mul(an, an,an);
	}
	mul(res, an,res);
	memcpy(an, res, sizeof(res));
}

1到n的所有数的约数(nlogn)

for (int i = 1; i < n; i++) 
{
	for (int j = i; j < n; j = j + i) {
		yueshu[j].push_back(i);
	}
}

差分

int an[100010];
int bn[100010];
int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		cin >> an[i];
	}
	bn[1] = an[1];
	for (int i = 2; i <= n; i++)//前缀和的逆向使用,an是bn的前缀和,由an得到bn,这样一次性操作an中k个数字同时增加减少,只需要对bn中两个数字进行操作即可
	{
		bn[i] = an[i] - an[i - 1];
	}
	while (m--)
	{
		int l, r, c;
		cin >> l >> r >> c;
		bn[l] += c;
		if (r < n)
			bn[r + 1] -= c;
	}
	an[1] = bn[1];
	for (int i = 2; i <= n; i++)
	{
		an[i] =an[i-1]+bn[i];
	}
	for (int i = 1; i <= n; i++)
	{
		cout << an[i] << " ";

	}
	return 0;

}

文章作者: ycx
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ycx !
评论
 上一篇
图论 图论
图是计算机中常用的一种存储结构,图论是数学的一个分支,研究图上的优化算法。
2024-07-27
下一篇 
数据结构 数据结构
分享算法中常见的一些高级数据结构,包括trie字典树,并查集,线段树等
2024-07-27
  目录