基础算法

64位整数乘法 [https://www.acwing.com/problem/content/92/]

sol:
将 b 进行二进制拆分,就变成了计算$a*(2^0 + 2^1 + 2^2 +....) $,结合乘法分配律,对每一项进行相加,得到结果。 (O(logN))

LL mul(LL a, LL b, LL p) {
	LL res = 0;
	for(; b; b >>= 1) {
		if( b & 1) 
			res = (res + a) % p;
		a = 2 * a % p;
	} 
	return res;
} 

费解的开关 [https://www.acwing.com/problem/content/description/97/]

sol:
类似于这一道题目[https://www.luogu.com.cn/problem/CF1239A],CF的这道题是确定第一行和第一列之后所有的状态都确定了。而本题是确定了第一行的状态就
可以推出剩下的开关状态。我却没有想到,原因是我没有考虑到一个性质,就是按开关的顺序是无关的。所以我们可以枚举第一行的所有状态,从而推出所有状态。

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 10;
int R = 5; 
int a[N][N], b[N][N];
char s[N][N]; 

void FilpBit(int x, int y) {
	a[x][y] ^= 1;
	a[x + 1][y] ^= 1;
	a[x - 1][y] ^= 1;
	a[x][y + 1] ^= 1;
	a[x][y - 1] ^= 1;
}

int allLight() {
	int cnt = 0;
	for(int i = 2; i <= R; i ++) {
		for(int j = 1; j <= R; j ++) {
			if(a[i - 1][j] == 0) {
				FilpBit(i, j);
				cnt ++;
		    }
		}
		if( i == R) {
			for(int j = 1; j <= R; j ++) {
				if( a[i][j] != 1)    return 7;
			}
		}
	}
	return cnt;
} 

int main()
{
	int T;
	scanf("%d", &T);
	while(T --) {
		int ans = 7;
		for(int i = 1; i <= R; i ++) {
			scanf("%s", s[i] + 1);
			for(int j = 1; j <= R; j ++) {
				a[i][j] = s[i][j] - '0';
				b[i][j] = a[i][j];
			} 
		}
		for(int s = 0; s < (1 << R); s ++) {
			int cnt = 0;
			for(int k = 0; k < R; k ++) {
				if( (s >> k) & 1) {
					FilpBit(1, k + 1);
					cnt ++;
				} 
			} 
			ans = min(allLight() + cnt, ans);
			memcpy(a, b, sizeof(b));
		}
		if( ans > 6)    ans = -1;
		printf("%d
", ans);
	}
	return 0;
}

约数之和 [https://www.acwing.com/problem/content/99/]

sol:
首先利用约数个数和定理,可以得到,题目就是等比数列求和。可以用分治来解决。分类讨论,B为偶数和B为奇数。
(f(n) = sum_{i = 0}^{n}A^i)
再结合快速幂,f(n)就可以由f(n/2)递推过来了。

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int N = 100, mod = 9901; 
typedef long long LL;

int p[N], cnt;
LL r[N];

void divide(int n) {
	for(int i = 2; i * i <= n; i ++) {
		if( n % i == 0) {
			int t = 0;
			p[++cnt] = i;
			while(n % i == 0) {
				n /= i;
				t ++;
			}
			r[cnt] = t;
		} 
	}
	if( n > 1) {
		p[++cnt] = n;
		r[cnt] = 1;
	}
}

LL qmi(LL a, LL b) {
	LL res = 1;
	for(; b; b >>= 1) {
		if(b & 1)
			res = res * a % mod;
		a = a * a % mod;
	}
	return res;
}

LL solve(LL a, LL b) {
	if( b == 0)
		return 1ll;
	LL t = solve(a, b / 2);
	if( b % 2 == 1) {
		LL tmp = (qmi(a, (b + 1) / 2) + 1 ) * t % mod;
		return tmp;
    } else {
    	LL tmp = ( qmi(a, b / 2) * (t - 1) % mod + t % mod) % mod;
    	return tmp;
	}
} 

int main()
{
	int a, b;
	LL ans = 1;
	scanf("%d%d", &a, &b);
	divide(a);
	for(int i = 1; i <= cnt; i ++) {
		r[i] *= b;
		ans = ans * solve((LL)p[i], r[i]) % mod;
	}
	if(a == 0)
	    ans = 0;
	printf("%lld
", ans);
	return 0;
} 
原文地址:https://www.cnblogs.com/wyy0804/p/13619887.html