算竞小技巧(持续更新)

// 去重 + 排序
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());

set<int> s(a.begin(), a.end());

// 全排列
vector<int> p(n);
iota(p.begin(), p.end, 0);
do {

} while (next_permutation(p.begin(), p.end()));

// lower_bound 的用法
sort(a.begin(), a.end());
auto t = lower_bound(a.begin(), a.end(), x); // t 为大于等于 x 的第一个迭代器
if (t == a.end()) cout << "未找到满足条件的元素" << '\n';
else cout << t - a.begin() << '\n';

// 翻转字符串
string str = string(s.rbegin(), s.rend());
reverse(s.begin(), s.end());

// 回文字符串的判断
if (s == string(s.rbegin(), s.rend())) cout << "Yes" << '\n';
else cout << "No" << '\n';

// 不改变原序列的排序
vector<int> p(n);
iota(p.begin(), p.end(), 0);
sort(p.begin(), p.end(),
    [&] (int i, int j) {
        if (a[i] == a[j]) return i < j; // 加上这个可以保证稳定性
        return a[i] < a[j];
        // return pair(a[i], i) < pair(a[j], j);
});

// 二进制中 1 的个数
int a = __builtin_popcount(x); // unsigned int
int b = __builtin_popcountll(y); // unsigned long long

// 二进制中末尾有几个 0 
int t = __builtin_ctz(x); // unsigned int
int x = __cuiltin_ctzll(x); // unsigned long long

// 二进制最高位 1 的位置
int pos1 = 31 - __builtin_clz(x); // int
int pos2 = 32 - __builtin_clz(x); // unsigned int
int pos3 = 63 - __builtin_clzll(y); // long long
int pos4 = 64 - __builtin_clzll(y); // unsigned long long

// 重载运算符
bool operator<(const Name& q) const {
        if (a != q.a) return a < q.a;
        if (b != q.b) return b < q.b;
        return c < q.c;
}

// lambda 表达式实现递归
auto dfs(auto self, int u) -> void {
        self (self, u + 1);
        // return self(self, u + 1);  
        // == self(self, u + 1); return;
};

// 用函数关闭所有程序
exit(0);
 
// 堆 (优先队列)
poriority_queue<int> q; // 默认大根堆
poriority_queue<int, vector<int>, greater<int>> u; // 小根堆

// assign 重新分配容器内容
a.assign(n + 1, 0); // vector用法

// 容器中的最小值和最大值
int t = *min_element(a.begin(), a.end()); // 最小值
int s = *max_element(a.begin(), a.end()); // 最大值

// cout 设置小数位数
// 采用 “银行家舍入法”,大体上遵循四舍五入
cout << fixed << setprecision(10);

// STL 快速转移 (move 函数) (省 '=' 开临时变量的时间)
map<int, vector<int>> Map;
Map[a] = move(Map[b]);  // 直接强制转移所有权,Map[b] 会变为空
Map.erase(b);  // 将下标 b 从 Map 中删除

// 梅森旋转生成伪随机数 (用作哈希,或者需要随机数的场景)
// mt19937_64 就是“梅森旋转算法,周期 $2^{19937}-1$,输出64位整数”的意思
mt19937_64 rnd(233);
unsigned long long x = rnd();

// 位运算的易错
if ((u & v) != u) continue;

// 枚举所有二进制数的子集 (时间复杂度3^n)
for (int i = 1; i < (1 << n); i ++) {
    for (int j = i; j; j = (j - 1) & i) {

    }
}

// map迭代器使用方法
auto t = mp.find(x);
int key = t->first, value = t->second;
t = next(t);
posted @ 2025-09-16 10:16  he_jie  阅读(12)  评论(1)    收藏  举报