C语言-算法-数论基础

【模板】快速幂

题目描述

给你三个整数 a , b , p a,b,p a,b,p,求 a b   m o d   p a^b \bmod p abmodp

输入格式

输入只有一行三个整数,分别代表 a , b , p a,b,p a,b,p

输出格式

输出一行一个字符串 a^b mod p=s,其中 a , b , p a,b,p a,b,p 分别为题目给定的值, s s s 为运算结果。

样例 #1

样例输入 #1

2 10 9

样例输出 #1

2^10 mod 9=7

提示

样例解释

2 10 = 1024 2^{10} = 1024 210=1024 1024   m o d   9 = 7 1024 \bmod 9 = 7 1024mod9=7

数据规模与约定

对于 100 % 100\% 100% 的数据,保证 0 ≤ a , b < 2 31 0\le a,b < 2^{31} 0a,b<231 a + b > 0 a+b>0 a+b>0 2 ≤ p < 2 31 2 \leq p \lt 2^{31} 2p<231

代码

#include 
#include 

int main(int argc, char *argv[])
{
	long long a, b, p, ans,x , y;
	scanf("%lld %lld %lld", &a, &b, &p);
	x = a;
	y = b;
	ans = 1;
	x = x % p;
	
	while (y > 0)
	{
		if ((y % 2) == 1)
		{
			ans = (ans * x) % p;
		}
		y = y / 2;
		x = (x * x) % p;
	}
	printf("%lld^%lld mod %lld=%lld", a, b, p, ans);
	
	return 0;
}

「EZEC-2」异或

题目描述

T T T 组询问,每次给定两个正整数 n , l n,l n,l

你需要构造一个长度为 l l l 的正整数序列 a a a(编号从 1 1 1 l l l),

且满足 ∀ i ∈ [ 1 , l ] \forall i\in[1,l] i[1,l],都有 a i ∈ [ 1 , n ] a_i\in[1,n] ai[1,n]

求:

∑ i = 1 l ∑ j = 1 i − 1 a i ⊕ a j \sum_{i=1}^l\sum_{j=1}^{i-1}a_i\oplus a_j i=1lj=1i1aiaj

的最大值。

为了避免答案过大,对于每组询问,只需要输出这个最大值对 1 0 9 + 7 10^9+7 109+7 取模的结果。

输入格式

第一行一个整数 T T T,表示数据组数。

接下来第 2 2 2 行到第 T + 1 T+1 T+1 行,每行两个整数 n , l n,l n,l ,分别代表 a i a_i ai 的最大取值与 a a a 的长度。

输出格式

T T T 行,每行一个整数,对应每组询问的答案对 1 0 9 + 7 10^9+7 109+7 取模的结果。

样例 #1

样例输入 #1

1
2 3

样例输出 #1

6

样例 #2

样例输入 #2

2
114 514
1919 180

样例输出 #2

8388223
16580700

提示

【样例解释 #1】
n = 2 , l = 3 n=2,l=3 n=2,l=3 a a a { 1 , 2 , 1 } \{1,2,1\} {1,2,1} 的任一排列时可以得到最大值,为 ( 1 ⊕ 2 ) + ( 1 ⊕ 1 ) + ( 2 ⊕ 1 ) = 6 (1\oplus2)+(1\oplus1)+(2\oplus1)=6 (12)+(11)+(21)=6,易证明此时原式有最大值。


【数据规模与约定】

测试点编号 T ≤ T\le T n ≤ n\le n l ≤ l\le l
1 ∼ 5 1\sim5 15 1 1 1 10 10 10 5 5 5
6 6 6 5 × 1 0 5 5\times 10^5 5×105 1 0 12 10^{12} 1012 2 2 2
7 7 7 5 × 1 0 5 5\times 10^5 5×105 1 0 12 10^{12} 1012 3 3 3
8 ∼ 10 8\sim10 810 5 × 1 0 5 5\times 10^5 5×105 1 0 12 10^{12} 1012 1 0 5 10^5 105

对于 100 % 100\% 100% 的数据,满足 1 ≤ T ≤ 5 × 1 0 5 1\le T\le 5\times10^5 1T5×105 1 ≤ n ≤ 1 0 12 1\le n\le 10^{12} 1n1012 2 ≤ l ≤ 1 0 5 2\le l \le 10^5 2l105


【提示】

  1. ⊕ \oplus 」是按位异或符号。如果您不知道什么是按位异或,可以参考这里。
  2. 取模是一种运算, a a a b b b 取模代表将 a a a 赋值为 a a a 除以 b b b 所得到的余数。
    在 C++ / Python 中的取模符号为 %,在 Pascal 中的取模符号为 mod
  3. ∑ \sum 是求和符号。如果您不知道什么是 ∑ \sum 符号,可以参考这里。
  4. 请注意数据的读入输出对程序效率造成的影响。

代码

【模板】线性筛素数

题目背景

本题已更新,从判断素数改为了查询第 k k k 小的素数
提示:如果你使用 cin 来读入,建议使用 std::ios::sync_with_stdio(0) 来加速。

题目描述

如题,给定一个范围 n n n,有 q q q 个询问,每次输出第 k k k 小的素数。

输入格式

第一行包含两个正整数 n , q n,q n,q,分别表示查询的范围和查询的个数。

接下来 q q q 行每行一个正整数 k k k,表示查询第 k k k 小的素数。

输出格式

输出 q q q 行,每行一个正整数表示答案。

样例 #1

样例输入 #1

100 5
1
2
3
4
5

样例输出 #1

2
3
5
7
11

提示

【数据范围】
对于 100 % 100\% 100% 的数据, n = 1 0 8 n = 10^8 n=108 1 ≤ q ≤ 1 0 6 1 \le q \le 10^6 1q106,保证查询的素数不大于 n n n

代码

#include 
#include 
#include 
void S(); // 用筛法找出所有小于n的素数
#define MAX 2000000
long long n, q;
int prime[MAX], cnt = 0; // prime数组用于存储所有小于n的素数,cnt用于记录素数的数量
int isPrime[MAX] = {0}; // isPrime数组用于标记每个数是否为素数,0表示是素数,1表示不是素数

int main(int argc, char *argv[])
{
	long long k, i;
	scanf("%lld %lld", &n, &q);
	S(); // 找出所有小于n的素数
	
	for (i = 1; i <= q; i++) // 输出第k小的素数
	{
		scanf("%lld", &k);
		printf("%lld\n", prime[k - 1]); 
	}
	
	return 0;
}

void S() // 用筛法找出所有小于n的素数
{
	long long limit, i, j;
	limit = sqrt(n) + 1;
	for (j = 2; j <= limit; j++)
	{
		if (isPrime[j] == 0) // 如果j是素数,则将所有p的倍数标记为非素数
		{
			for (i = j * j; i <= n; i += j)
			{
				isPrime[i] = 1;
			}
		}
	}
	for (j = 2; j <= n; j++) // 将所有标记为素数的数存入prime数组
	{
		if (isPrime[j] == 0)
		{
			prime[cnt++] = j;
		}
	}
}

你可能感兴趣的:(C语言-算法,算法,c语言,开发语言)