A: 素数查询(Easy)
一个欧拉筛然后查询完事
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 2e5 + 7;
int isprime[MAXN]; //保存素数
int vis[MAXN]; //初始化
void eulerSieve()
{
int cnt = 0;
memset(vis, 0, sizeof(vis)); //0是素数,1是合数
for (int i = 2; i < MAXN; i++){
if (!vis[i])
isprime[cnt++] = i;
for (int j = 0; j < cnt && i * isprime[j] < MAXN; j++){
vis[i * isprime[j]] = 1;
if (i % isprime[j] == 0){
break;
}
}
}
}
int main()
{
eulerSieve();
int a;
while(cin >> a && a){
if(!vis[a]){
cout << "Yes" << endl;
}
else cout << "No" << endl;
}
return 0;
}
B: 素数查询(Hard)
还是欧拉筛,可以把每个数(包括这个数)前面的素数个数使用一个前缀素数个数数组 pre[ ] 存下来,求 [ a, b ] 区间素数个数时,只需访问 pre[b] - pre[a-1] 即可
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 2e5 + 7;
int isprime[MAXN]; //保存素数
int vis[MAXN]; //打表
int pre[MAXN]; //前缀素数个数
void eulerSieve()
{
int cnt = 0;
memset(vis, 0, sizeof(vis)); //0是素数,1是合数
for (int i = 2; i < MAXN; i++){
if (!vis[i])
isprime[cnt++] = i;
pre[i] = cnt; //存下前缀素数个数
for (int j = 0; j < cnt && i * isprime[j] < MAXN; j++){
vis[i * isprime[j]] = 1;
if (i % isprime[j] == 0){
break;
}
}
}
}
int main()
{
eulerSieve();
int T, a, b;
scanf("%d", &T);
while(T--){
scanf("%d %d", &a, &b);
cout << pre[b] - pre[a-1] << endl;
}
return 0;
}
C: 求斐波那契数列
构造出转移矩阵 ,我们可以通过这个转移矩阵让初始矩阵
变成
。
而我们的初始矩阵值也是 ,所以这个题实际上就是求
。由于数据较大,注意使用 long long 类型。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define MOD 1000000009
typedef long long LL;
const int maxn = 2;
struct Matrix{
LL m[maxn][maxn];
}ans, res;
Matrix mul(Matrix a, Matrix b){
Matrix tmp;
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
tmp.m[i][j] = 0;
}
}
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
for(int k = 0; k < 2; k++){
tmp.m[i][j] += ((a.m[i][k] % MOD) * (b.m[k][j] % MOD)) % MOD;
tmp.m[i][j] %= MOD;
}
}
}
return tmp;
}
void mpoww(LL n){
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
if(i == j){
ans.m[i][j] = 1;
}
else ans.m[i][j] = 0;
}
}
while(n){
if(n & 1){
ans = mul(ans, res);
}
res = mul(res, res);
n >>= 1;
}
}
int main()
{
LL n;
cin >> n;
res.m[0][0] = 1;
res.m[0][1] = 1;
res.m[1][0] = 1;
res.m[1][1] = 0;
mpoww(n);
cout << ans.m[0][1] << endl;
return 0;
}
D: 一个简单的数学问题
构造出转移矩阵 ,初始矩阵为
,所以
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 11;
struct Matrix{
int m[maxn][maxn];
}f, e; // f为转移矩阵,e为初始矩阵
int k, MOD;
Matrix mul(Matrix a, Matrix b){
Matrix tmp;
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
tmp.m[i][j] = 0;
}
}
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
for(int k = 0; k < 10; k++){
tmp.m[i][j] += ((a.m[i][k] % MOD) * (b.m[k][j] % MOD)) % MOD;
tmp.m[i][j] %= MOD;
}
}
}
return tmp;
}
Matrix mpoww(Matrix res, int n){
Matrix ans;
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
if(i == j){
ans.m[i][j] = 1;
}
else ans.m[i][j] = 0;
}
}
while(n){
if(n & 1){
ans = mul(ans, res);
}
res = mul(res, res);
n >>= 1;
}
return ans;
}
int main()
{
while(scanf("%d %d", &k, &MOD) == 2){
memset(f.m, 0, sizeof f.m);
for(int i = 0; i < 10; i++){
scanf("%d", &f.m[0][i]);
if(i < 9) f.m[i+1][i] = 1;
e.m[9 - i][0] = i;
}
if(k < 10){
cout << k << endl;
}
else {
Matrix tmp = mpoww(f, k - 9);
int ans = 0;
for(int i = 0; i < 10; i++){
ans = (ans + (tmp.m[0][i] * e.m[i][0]) % MOD) % MOD;
}
cout << ans << endl;
}
}
return 0;
}
E: 小小粉刷匠(完整船星版本)
公式为 ,直接快速幂即可。
#include <iostream>
#include <cmath>
using namespace std;
const int mod = 1000000009;
typedef long long ll;
ll poww(ll a, ll n)
{
ll res = 1;
while (n)
{
if (n & 1)
res = (res * a) % mod;
a = (a * a) % mod;
n >>= 1;
}
return res;
}
int main()
{
ll n;
while (cin >> n)
{
cout << (4 * poww(3, n - 2)) % mod << endl;
}
return 0;
}