2024.9.29校测
T1
题目描述
其中
其中
又有:
输入格式
第一行包含两个整数:
输出格式
输出一行包含一个数,表示答案。
输入样例
3 1
输出样例
1000000005
样例解释
数据规模
对于
对于
对于
题解
首先根据欧拉反演 (具体可见数论学习笔记(一)(2024.7.25)),
考虑改变枚举顺序,则原式
现在就可以通过线性筛筛出
完整代码
#include<bits/stdc++.h>
using namespace std;
const int PP = 1e7 + 9, MOD = 1e9 + 7;
int prime[PP], h[PP], sum[PP], isPrime[PP], p_cnt;
short mu[PP], g[PP];
int n, m, ans;
int qpow(int a, int b){
int ret = 1;
while(b > 0){
if(b & 1)
ret = 1ll * ret * a % MOD;
a = 1ll * a * a % MOD;
b >>= 1;
}
return ret;
}
void getPrime(int n){
mu[1] = h[1] = 1;
for(int i = 2; i < n; i++){
if(!isPrime[i]) {
prime[++p_cnt] = i;
g[i] = 1;
h[i] = 2;
mu[i] = -1;
}
for(int j = 1; j <= p_cnt && i * prime[j] < n; j++){
int tmp = prime[j];
isPrime[i * tmp] = tmp;
if(i % tmp == 0) {
g[i * tmp] = g[i] + 1;
h[i * tmp] = h[i] / (g[i] + 1) * (g[i] + 2);
mu[i * tmp] = 0;
break;
}
g[i * tmp] = g[tmp];
h[i * tmp] = h[i] * h[tmp];
mu[i * tmp] = -mu[i];
}
}
for(int i = 1; i <= n; i++)
sum[i] = (sum[i - 1] + qpow(i, m + 1) * mu[i]) % MOD;
}
int main(){
freopen("facsum.in", "r", stdin);
freopen("facsum.out", "w", stdout);
scanf("%d%d", &n, &m);
getPrime(n + 1);
for(int i = 1; i <= n; i++){
int now = qpow(i, m);
now = (1ll * now * h[i] % MOD * sum[n / i]) % MOD;
ans = ((ans + now) % MOD + MOD) % MOD;
}
printf("%d\n", ans);
return 0;
}
T2
题目描述
现在,
的。(保证
输入格式
第
接下来
输出格式
对于每组数据,输出一行,包含一个整数,表示模意义下本质不同的数有多少个。
输入样例
2
1 3
2 5
输出样例
1
4
样例解释
对于第一组数据,数列是:
对于第二组数据,数列(取模以后)是:
数据规模
对于
对于
题解
在这里介绍一下
我们考虑将
现在用
由于
那么就可以枚举同余式右边的
考虑本题如果出现
完整代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
int BSGS(int a, int b, int p){
int k = sqrt(p) + 1;
unordered_map <int, int> Hash;
for(int i = 0, j = b % p; i < k; i++){
Hash[j] = i;
j = j * a % p;
}
int ak = 1;
for(int i = 0; i < k; i++)
ak = ak * a % p;
for(int i = 1, j = ak; i <= k; i++){
if(Hash.count(j))
return i * k - Hash[j];
j = j * ak % p;
}
exit(0);
}
int a, b, p, T;
signed main(){
freopen("group.in", "r", stdin);
freopen("group.out", "w", stdout);
scanf("%lld", &T);
while(T--){
scanf("%lld%lld", &a, &p);
printf("%lld\n", BSGS(a, 1, p));
}
return 0;
}
T3
题目描述
于是,他写下了这样一个数:
输入格式
第
接下来
输出格式
对于每组数据,输出一行,包含一个整数,表示答案。
输入样例
2
1 3 4
1 4 5
输出样例
0
4
样例解释
对于第一组数据,数列是:
对于第二组数据,数列是:
数据规模
对于
对于
对于
题解
首先根据 Lucas 定理,
如果要让这个组合数等于
完整代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 39;
int f[N][2] ,digl[N], digr[N], dign[N];
int DFS_l(int pos, int fl){
if(pos == -1)
return 1;
if(f[pos][fl] != -1)
return f[pos][fl];
f[pos][fl] = 0;
int ed = min((fl ? digl[pos] : 4), dign[pos]);
for(int i = 0; i <= ed; i++)
f[pos][fl] += DFS_l(pos - 1, fl && i == digl[pos]);
return f[pos][fl];
}
int DFS_r(int pos, int fl){
if(pos == - 1)
return 1;
if(f[pos][fl] != -1)
return f[pos][fl];
f[pos][fl] = 0;
int ed = min((fl ? digr[pos] : 4), dign[pos]);
for(int i = 0; i <= ed; i++)
f[pos][fl] += DFS_r(pos - 1, fl && i == digr[pos]);
return f[pos][fl];
}
signed main(){
freopen("ccount.in", "r", stdin);
freopen("ccount.out", "w", stdout);
int t;
scanf("%d", &t);
while(t--){
int l, r, n;
scanf("%lld%lld%lld", &l, &r, &n);
int L = l, R = r;
l--;
for(int i = 0; i < 30; i++){
digl[i] = l % 5;
digr[i] = r % 5;
dign[i] = n % 5;
l /= 5;
r /= 5;
n /= 5;
}
memset(f, -1, sizeof(f));
int ansr = DFS_r(29, 1);
memset(f, -1, sizeof(f));
int ansl = DFS_l(29, 1);
printf("%lld\n", (R - L + 1) - (ansr - ansl));
}
return 0;
}
本文来自博客园,作者:JPGOJCZX,转载请注明原文链接:https://www.cnblogs.com/JPGOJCZX/p/18442374
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】