24暑假集训day3下午
实现代码:
int exgcd(int a,int b, int &x, int &y){
if(b == 0){
x = 1;
y = 0;
return a;
}
int d = exgcd(b, a % b, x, y);
int k = x;
x = y;
y = k - (a / b) * y;
return d;
}
int main(){
int a = read(), b = read();
int x, y;
int d = exgcd(a, b, x, y);
cout << d << " " << x << " " << y << '\n';
return 0;
}
#define ll long long
ll fac[N], ifac[N];
const ll p=998244353;
ll power(ll a, ll b){
ll ret = 1;
while (b){
if(b & 1){
ret = ret * a % p;
}
a = a * a % p;
b >>= 1;
}
return ret;
}
ll c(int a, int b){
if(a < b || b < 0){
return 0;
}
return fac[a] * ifac[b] % p * ifac[a - b]% p;
}
void initialize(){
fac[0]= 1;
for(int i=1; i < N; i++){
fac[i] = fac[i - 1] * i % p;
}
ifac[N - 1] = power(fac[N - 1], p - 2);
for(int i = N - 2;i >= 0;i--){
ifac[i]= ifac[i + 1] * (i + 1) % p;
}
}
思路:
我们知道
所以
问题变为计算
std:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<unordered_map>
#include<bitset>
#define int long long
using namespace std;
const int MAXN=100005;
inline int read(){
int x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9'){
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9'){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
signed main(){
int q;
long long ans;
q=read();
while(q--){
int l,r;
l=read();
r=read();
ans=(l+r)%9*(r-l+1)%9*5%9;
cout<<ans<<'\n';
}
return 0;
}
中国剩余定理
给定一些
我们只需要每次合并两个方程。
现在考虑
即
代入得
。使用扩展欧几里得算法计算出
将两个方程合并为一个新的方程
实际上
思路:
若
假设
具体地,设
如果此时
质数筛
素数判断的方法
- 既然第一种方法时间复杂度太大,那么我们要考虑一种新的方式。首先给出这种方法的名字——埃式筛。听上去是不是一个很高大上的名字,但其实原理很简单,我们用一个数组来存放n以内的所有质数,我们要用到一个布尔数组来标记n以内的所有不是质数的数(也要标记1,1既不是质数也不是合数)。再标记此质数所有的倍数(因为质数所有的倍数都不是质数)。最后输出所有质数
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
bool is[10005];
int prim[10005];
int cnt=0;
void Aprime(int n){
is[1]=1;//1既不是质数也不是合数
for(int i=2;i<=n;i++){//遍历2~n之间的所有整数
if(is[i]==0){//如果没有被标记过,说明是质数
prim[++cnt]=i;//存储质数
for(int j=i*2;j<=n;j+=i){//标记所有此质数的倍数
is[j]=1;
}
}
}
}
int main(){
int n;
cin>>n;
Aprime(n);//调用函数
for(int i=1;i<=cnt;i++){
cout<<prim[i]<<"\n";//输出质数
}
return 0;
}
素数判断的方法2:
埃式筛的缺点在于有和数被重复标记了多次,所以还不是最优解,这里奉上更快的办法——欧拉筛。欧拉筛,也叫线性筛,是更快的判断质数的方法。其思路在埃式筛的基础上有所改进,让质数库里的每个质数分别与循环中的i相乘,如果i取余这个质数等于0,则直接跳出循环,避免重复标记,节省时间。
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
bool is[10005];
int prim[10005];
int cnt=0;
void Aprime(int n){
is[1]=1;//1既不是质数也不是合数
for(int i=2;i<=n;i++){
if(is[i]==0){//如果没有被标记过,说明是质数
prim[++cnt]=i;//存储质数
}
for(int j=1;j<=cnt&&i*prim[j]<=n;j++){//质数不超过n
is[i*prim[j]]=1;//用新数去乘每一个质数
if(i%prim[j]==0){
break;//不重复标记,取余等于0就跳出循环
}
}
}
}
int main(){
int n;
cin>>n;
Aprime(n);//调用函数
for(int i=1;i<=cnt;i++){
cout<<prim[i]<<"\n";//输出质数
}
return 0;
}
思路:
由于本题数据较水,对每个子集和暴力试除就能过。
但如果数据不水,需要使用线性筛,并且要压一下空间。
std:
#include<bits/stdc++.h>
using namespace std;
bool isprime(int a){
for(int i=2;i*i<=a;i++)if(a%i==0)return 0;
return 1;
}
long long ans,a[25],n,k;
void dfs(int m, int sum, int s){
if(m == k){
if(isprime(sum))ans++;
return ;
}
for(int i = s; i<n;i++)dfs(m+1,sum+a[i],i+1);
return ;
}
int main(){
scanf("%d%d",&n,&k);
for(int i = 0; i < n; i++)scanf("%d",&a[i]);
dfs(0, 0, 0);
printf("%d\n",ans);
return 0;
}
思路:
假设一开始是 𝑥 ,操作一次变为 𝑚 ,操作两次变为 𝑛 。
第一次操作选的
第二次操作选的
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<unordered_map>
#include <climits>
#define ll long long
using namespace std;
const int MAXN = 1000010;
const int N = 1000000;
int n;
bool b[MAXN];
int prime[MAXN], idx;
int f[MAXN];
int ans = INT_MAX;
inline int get(int x){
if (!b[x]) return INT_MAX;
return x - f[x] + 1;
}
int main(){
scanf("%d", &n);
for (int i = 2; i <= N; ++i){
if (!b[i]) prime[++idx] = f[i] = i;
for (int j = 1; j <= idx && (ll) i * prime[j] <= N; ++j){
b[i * prime[j]] = true;
f[i * prime[j]] = max(f[i], prime[j]);
if (i % prime[j] == 0) break;
}
}
for (int i = get(n); i <= n; ++i)
ans = min(ans, get(i));
if (ans == INT_MAX) puts("-1");
else printf("%d\n", ans);
return 0;
}
思路:
所以
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<unordered_map>
#include<bitset>
#define int long long
using namespace std;
const int MAXN=100005;
inline int read(){
int x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9'){
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9'){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
signed main(){
int n;
n=read();
if(n%2!=0){
if(((n-1)/2)%2!=0){
cout<<0;
}else{
cout<<1;
}
}else{
if(((n-1)/2)%2!=0){
cout<<(0^n);
}else{
cout<<(1^n);
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!