trick

整理各种实(wai)用(men)技(xie)巧(dao)

光速幂

对于形如 \(a^b mod\ p\) 的柿子,常见的处理方法是快速幂 \(O(0)-O(\log b)\)(预处理-询问)。

如果某些题目要求单次询问 \(O(1)\),这时候就可以请出光速幂 \(O(\sqrt n)-O(1)\),但是注意光速幂要求底数和模数都固定,所以应用不广。

具体而言,我们将幂指数分成 \(k\) 块,预处理出 \(a^s,a^{2s}...,a^{ks}\)
\(a,a^2...a^{s-1}\),这样就有

\[a^b = a^{\lfloor\frac{b}{s}\rfloor \times s+{b\ mod\ s}} \mod p \]

如果 \(p\) 是素数直接预处理到 \(p-1\) 即可。(或者到 \(φ(p)\),但没必要)。

code:

点击查看代码
void predeal(int x){
	sq = sqrt(mod);
	ph[0][0] = ph[0][1] = 1;
	for(int i = 1; i <= sq; i++)
		ph[i][0] = ph[i-1][0] * x % mod;
	ph[1][1] = ph[sq][0];
	for(int i = 2; i <= sq; i++)
		ph[i][1] = ph[i-1][1] * ph[1][1] % mod;
	return;
}

int power(int x){return ph[x/sq][1] * ph[x%sq][0] % mod;}

分治 popcount:

可以用 __builtin_popcount,但是这里介绍一种神奇的“分治算法”。
考虑把一个二进制数 \(x\) 两位一组分组,那么这两位的结果就是两位相加,类似于 FFT 中的蝶形优化,我们把这两位的答案存在他的相应位置上。
具体的,我们用 x 与上 \(01010101_2\) 得到一半答案,再把 x 右移一位,继续算另一半答案,最后加起来即可。
code:

const unsigned int bit1 = 0x55555555; // 01010101
const unsigned int bit2 = 0x33333333; // 00110011
const unsigned int bit4 = 0x0f0f0f0f; // 00001111
const unsigned int bit8 = 0x00ff00ff; // 同上
const unsigned int bit16 = 0x0000ffff;
int popcount(int x){
	x = (x & bit1) + ((x >> 1) & bit1);
	x = (x & bit2) + ((x >> 2) & bit2);
	x = (x & bit4) + ((x >> 4) & bit4);
	x = (x & bit8) + ((x >> 8) & bit8);
	x = (x & bit16) + ((x >> 16) & bit16);
	return x;
}

基数排序

这是个非常玄学的东西,甚至加入优化后能 \(5s\)\(n = 1e8\) 的数列。
每次按当前最低位插入一个桶里,之后从桶里从低到高依次取出,继续排下一位。

int n, p10[MAXN];
int a[MAXN], b[MAXN];
vector<int> t[MAXN];

void Sort( ){
	int mx = 0, mxbit = 0;
	for(int i = 1; i <= n; i++) mx = max(mx, a[i]);
	p10[0] = 1;
	for(int i = 1; i <= 9; i++) p10[i] = p10[i-1] * 10;
	while(mx){mxbit++; mx /= 10;}
	for(int tt = 1; tt <= mxbit; tt++){
		for(int i = 1; i <= n; i++) t[(a[i] / p10[tt-1]) % 10].push_back(a[i]);
		int cur = 0;
		for(int i = 0; i < 10; i++){
			for(int j : t[i]) a[++cur] = j;
			t[i].clear( );
		}
	}
}

例题是:P4604 [WC2017] 挑战

bitset

玄学++,不少卡常题都能用 bitset 爆碾。
基本食用方法参考 oiwiki
这里介绍一种模拟 bitset 的方法,例题是:
P5539【XR-3】Unknown Mother-Goose

posted @ 2023-07-06 22:02  Kun_9  阅读(40)  评论(0编辑  收藏  举报