小技巧

可删除堆

可利用两个优先队列来实现维护删除任意元素的功能

思想 : 利用延迟删除

priority_queue<int,vector<int>,greater<int> > Q , p;
	while(Q.size())
	{
		if( Q.top() == p.top() )
			p.pop();
		else cout<<Q.top()<<' ';
		Q.pop();
	}

矩阵中的 乘法 与 加法

struct Matrix{
	ll a[M][M];
	
	Matrix(){
		for(int i = 0 ; i < M ; ++i)
			for(int j = 0 ; j < M ; ++j)
				a[i][j] = 0;
	}
};

Matrix operator + (const Matrix &a , const Matrix &b)
{
	Matrix c;
	
	for(int i = 0 ; i < M ; ++i)
		for(int j = 0 ; j < M ; ++j){
			c.a[i][j] = a.a[i][j] + b.a[i][j];
			c.a[i][j] %= mod;	
		}
		
	return c;
}
Matrix operator * (const Matrix &a , const Matrix &b)
{
	Matrix c;
	
	for(int i = 0 ; i < M ; ++i)
		for(int j = 0 ; j < M ; ++j)
			for(int k = 0 ; k < M ; ++k)
			{
				c.a[i][j] += a.a[i][k] * b.a[k][j] % mod;
				c.a[i][j] %= mod;
			}
		
	return c;
}

set

//寻找集合内是否存在 x
set<int> p;
if(p.find(x) == p.end()) //不存在


vector

vector<int> ve;

ve.pop_back() ; //删除尾部元素

//lower_bound 与 erase 的配合使用
auto f = lower_bound(ve.begin(),ve.end(),x); //注意这里与 set 的lower_bound的调用不同
ve.erase(f);

//配合 next_permutation
vector<int> ve(n)
for(...) cin >> ve[i];
sort(ve.begin(),ve.end()); //想要得到全排列必须要 sort
do{
	...
}while(next_permutation(ve.begin(),ve.end()));

//resize()
vector<vector<int>> ve(n);
for(int i = 0 ; i < n ; ++i) {
	int m ; cin >> m;
	ve[i].resize(m);
	for(int j = 0 ; j < m ; ++j)
		cin >> ve[i][j];
}

vector<pair<int &,int> > ve;


字符串

"sudek"[i] 可以取字符串的第 i 位

优先级


// ! 与 ++
ans += !deg[x]++ ; //先判断是否为 0 , 再加加.
ans += !++deg[x] ; //先加加 , 再判断是否为 0.


memset


memset(dis , 0xf7 , sizeof dis); //负的极大值
0xf7的两倍仍在 long long 的范围内


枚举技巧


ll x,y,z;
要求 x * y <= z;
枚举时防止爆 ll , x <= z / y
x * y <= z 等价 x <= z / y (在整除性质下)


cout

cout 保留小数位
cout << std::fixed << std::setprecision(10) << ans << '\n'; //保留 10 位小数

逆元

C(n , m)

auto C = [&] (int n , int m) {
	if (m > n) {
		return 0ll;
	}
	return fac[n] * invFac[m] % mod * invFac[n - m] % mod;
};

注意 invFac[0] = 1; 

invFac[0] = 1 , invFac[1] = 1;
for (int i = 2 ; i <= n ; ++i) {
	invFac[i] = invFac[i - 1] * inv[i] % mod;
}

证明 : /(m! * (n - m)!) => /m! /(n - m)!
	 : /m! = inv[m] * .. * inv[1] = invFac[m]
	 

debug


#define debug(x) std::cerr << #x << "=" << x << '\n'
这个宏的作用是输出变量x的名称和值。宏内部的#操作符被称为字符串化操作符,它将变量x的名称转换为字符串字面量

例如 debug(a) , 'a'是一个整数 , 宏展开之后变成
std::cerr << "a" << "=" << a << '\n';

输出的结果不会看到 "#" 本身

例子:
#define debug(x) std::cerr << #x << " = " << x << '\n'
#define debug_vec(vec) std::cerr << #vec << ": ["; for (auto x : vec) std::cerr << x << ' '; std::cerr << "] \n"


__int128

//输出__int128
void prin(__int128) {
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (x > 9) {
		prin(x / 10);
	}
	putchar(x % 10 + '0');
}

使用putchar时要打开同步流


浮点数判断大小

int check(D a , D b) {
	if ( (a - b) > esp ) return 1; // a > b;
	else if ( (b - a) > esp ) return -1; // a < b;
	else if ( fabs(a - b) < esp ) return 0; // a = b;
}

位运算

if ( (i & (i - 1)) == 0 ) // 2 ^ i;

posted @ 2022-03-30 22:59  xqy2003  阅读(29)  评论(0)    收藏  举报