可删除堆
可利用两个优先队列来实现维护删除任意元素的功能
思想 : 利用延迟删除
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;