竞码编程-蓝桥杯模拟赛2(大学生组&青少年组)

A. 试题A:完美车牌 5’

描述
有一些数字可以颠倒过来看,例如0、1、8颠倒过来还是本身,6颠倒过来是9,9颠倒过来看还是6,其他数字颠倒过来不构成数字。
类似的,一些多位数也可以颠倒过来看,比如106颠倒过来是901.
假设某个城市的车牌只由6位数字组成,每一位都可以取0到9。请问这个城市最多有多少个车牌180°倒过来恰好还是原来的车牌?
例如:车牌号:886988,倒过来还是886988
答案:125
(5 * 5*5 or 6个for循环嵌套,枚举每一个数字上的值,然后逐一判断,是否满足要求).

B. 试题B:完美日期 5’

描述
【问题描述】
不知天上宫阙,今夕是何年。
对于完美日期yyyy/mm/dd,wlxsq的定义是:
(1)年月日中均没有出现数字4,
(2)年月日的数位之和是8的倍数
例如:2020/02/02 就是一个完美日期,没有出现数字4,且数位之和是8的倍数。

wlxsq想知道从2020/02/22开始,第88个完美日期是哪个?

【答案提交】:

//2022/03/07
import java.util.Scanner;
public class Main{
	public static int is(int x) {
		int cnt=0;
		while(x>0) {
			cnt+=x%10;
			x/=10;
		}
		return cnt;
	}
	public static boolean ok(int x) {
		while(x>0) {
			if(x%10==4) return false;
			x/=10;
		}
		return true;
	}
  public static void main(String[] args){ 
	  int []a= {31,28,31,30,31,30,
			  31,31,30,31,30,31};
	  int cnt=-9;
	  for(int i=2020;;i++) {
		  if(!ok(i)) continue;
		  for(int j=1;j<13;j++) {
			  if(j==4) continue;
			  int m=a[j-1];
			  if(j==2 && ( i%400==0 ||(i%100!=0 &&i%4==0))) {
				  m++;
			  }
			  int h=is(i)+is(j);
			  for(int k=1;k<=m;k++) {
				  if((is(k)+h)%8==0 &&ok(k)) {
					  cnt++;
					  System.out.println(cnt+":"+i+"/"+j+"/"+k);
					  if(cnt==88) {
						  System.out.println(i+"/"+j+"/"+k);
						  return ;
					  }
				  }
			  }
		  }
	  }
  } 
}

C. 试题C:天机锁10’

描述
【问题描述】
天机锁,锁天机~
wlxsq在机缘巧合的情况下就获得一把天机锁。wlxsq迫不及待的想打开这把锁。该锁的密码是由八个数字构成的,每个数字都是[0,9]中的一个~
锁上面写道:
水(数字9)火(数字4)相生相克,同现同隐(要么都出现,要么都不出现),数量一致(且出现则数量得一样多)。
土(数字2)乃大地,为伊始(数字2一定出现)。
世间万物,不过五二(八个数字之和不超过52)。
此乃天机,一日一次之~
由于天机锁一天只能试一次,wlxsq想知道,总共有多少种方案~
答案:19811435
8个for循环,枚举所有的情况,逐一判断即可~
or
8个坑dfs一遍,对于每一种情况逐一判断即可。

//我的错误dfs,还不知道哪里错了,有大佬看出问题了望指出👀
import java.util.Scanner;
public class Main{
	public static int ans=0;
	public static void dfs(boolean f1,int cnt,int i,int sum) {
		if(cnt==8) {
			if(f1 && i==0 &&sum<=52) {
				ans++;
			}
			return ;
		}
		if(sum>52) {
			return ;
		}
		for(int j=0;j<=9;j++) {
			if(j==2) {
				dfs(true,cnt+1,i,sum+j);
			}else if(j==9) {
				dfs(f1,cnt+1,i+1,sum+j);
			}else if(j==4){
				dfs(f1,cnt+1,i-1,sum+j);
			}else dfs(f1,cnt+1,i,sum+j);
		}
	}
	public static void main(String[]args) {
		dfs(false,0,0,0);
		System.out.println(ans);
	}
}

D. 试题D:完美运算 10‘

描述
定义a1:表示数字A对应的三进制数位中1的个数

定义a2:表示数字A对应的三进制数位中2的个数

定义完美运算
A○B,如果∣a1−a2∣=∣b1−b2∣,A○B的值为1,否则为0.请问,在[1,2020] 区间,有多少对(A,B)的结果为1
例如:A=2,B=3,则a1=0,a2=1,b1=1,b2=0,满足∣a1−a2∣=∣b1−b2∣所以A○B的结果为1。

注意,
A=2,B=3构成的数对(2,3)与A=3,B=2构成的数对(3,2)算同一对。
更新:(2,2)也算一对哦~
枚举所有的数字A和所有的数字B。
然后将这两个数转成三进制,计算出a1 和a2 的值。

答案:
472701

public class Ma{
	public static int ans=0;
	public static int cha(int x) {
		int a1=0,a2=0;
		while(x>0) {
			int h=x%3;
			if(h==1) {
				a1++;
			}else if (h==2) {
				a2++;
			}
			x/=3;
		}
		return Math.abs(a1-a2);
	}
	public static void main(String[]args) {
		int a[]=new int[2030];
		for(int i=1;i<=2020;i++) {
			a[i]=cha(i);
		}
		for(int i=1;i<2020;i++) {
			for(int j=i+1;j<=2020;j++) {
				if(a[i]==a[j]) {
					ans++;
				}
			}
		}
		System.out.println(ans+2020);
	}
}

E. 试题E:三叉神树 15’

描述
图1
给定如图1所示三叉树,节点A为根节点,E,F,J,K,H,L为叶子节点。已知这12个节点的权值对应着数字[1,12],使得所有以非叶子节点为根的子树权值之和为偶数。

如下图2所示,为其中一种满足要求的方案。
图2
图2样例解释:

对于非叶子节点B:3 + 1 = 4
对于非叶子节点C:5 + 11 + 9 + 7 + 2 = 34
对于非叶子节点G:9 + 7 + 2 = 18
对于非叶子节点D:10 + 8 + 6 + 4 = 28
对于非叶子节点I:6 + 4 = 1
请求出所有满足条件的方案数!!
叶子节点:一棵树当中没有子结点(即度为0)的结点称为叶子结点
方法一:12个for循环逐一枚举,然后逐一判断~
方法二:全排列,然后逐一判断即可~
每一个节点记为a1,a2…,a11,a12表示节点i上的权值为ai。
然后将每个以非叶子节点为根的子树权值之和相加,判断是否为偶数即可。
答案:11404800

//方法一(笨方法)
public class Main{
	public static int ans=0;
	public static void main(String[]args) {
		for(int A=1;A<=12;A++) {
			for(int B=1;B<=12;B++) {
				if(A==B) continue;
				for(int C=1;C<=12;C++) {
					if(C==A||C==B) continue;
					for(int D=1;D<=12;D++) {
						if(D==A ||D==B||D==C) continue;
						for(int E=1;E<=12;E++) {
							if((B+E)%2!=0) continue;
							if(E==A ||E==B||E==C||E==D) continue;
							for(int F=1;F<=12;F++) {
								if(F==A ||F==B||F==C||F==D||F==E) continue;
								for(int G=1;G<=12;G++) {
									if(G==A ||G==B||G==C||G==D||G==E||G==F) continue;
									
									for(int J=1;J<=12;J++) {
										if(J==A ||J==B||J==C||J==D||J==E||J==F||J==G) continue;
										for(int K=1;K<=12;K++) {
											if(K==A ||K==B||K==C||K==D||K==E||K==F||K==G||K==J) continue;
											if((G+J+K)%2!=0) continue;
											if((C+F+G+J+K)%2!=0) continue;
											for(int H=1;H<=12;H++) {
												if(H==A ||H==B||H==C||H==D||H==E||H==F||H==G||H==J||H==K) continue;
												for(int I=1;I<=12;I++) {
													if(I==A ||I==B||I==C||I==D||I==E||I==F||I==G||I==J||I==K||I==H) continue;
													
													for(int L=1;L<=12;L++) {
														if(L==A ||L==B||L==C||L==D||L==E||L==F||L==G||L==J||L==K||L==H||L==I) continue;
														if((L+I)%2!=0) continue;
														if((D+H+I+L)%2!=0) continue;
														ans++;
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		System.out.println(ans);
	}
}

//全排列,递归排列好慢a
public class Ma{
	public static int []a=new int[15];
	public static int ans=0,cnt=0;
	public static void Swap(int i,int x) {
		int t=a[i];
		a[i]=a[x];
		a[x]=t;
	}
	public static boolean check() {
		if((a[2]+a[5])%2!=0) return false;
		if((a[3]+a[6]+a[7]+a[10]+a[11])%2!=0) return false;
		if((a[4]+a[8]+a[9]+a[12])%2!=0) return false;
		if((a[9]+a[12])%2!=0) return false;
		if((a[3]+a[6])%2!=0) return false;
		return true;
	}
	public static void Perm(int begin,int end) {
		int i;
		if(begin==end) {
//			cnt++;
			if(check()) {
				ans++;
			}
			return ;
		}else {
				for(i=begin;i<=end;i++) {
					Swap(begin,i);
					Perm(begin+1,end);
					Swap(begin,i);
				}
			}
	}
	public static void main(String[]args) {
		for(int i=1;i<=12;i++) a[i]=i;
		Perm(1,12);//递归求全排列	
		System.out.println(ans);
//		System.out.println(cnt);
	}
}

F. 试题F:JM斗牛 17’

描述
JM打完麻将,觉得太简单了,所以决定去斗牛,挑战一下高难度。

一副牌共54张牌,即采用牌大王(1张),小王(1张),K,Q,J,10,9,8,7,6,5,4,3,2,A。除了大小王,其余牌型均为4张。故4*13+2=54张

斗牛则是每人5张牌,计算5张牌的构成的点数,然后比较点数大小。

关于点数计算:

大王(S),小王(S),K,Q,J都当成是10点,A当成是1点,其余牌都当其本身的点数。 大王,小王均用大写字母S表示
每位玩家5张牌,玩家用手上任意的3张牌组合(且只能用3张牌组成10的倍数),使其点数之和为10的倍数,这样就称之为“牛”。
然后将剩余的2张牌点数之和取个位数,如这2张牌之和也为10的倍数,则组成“牛牛”牌型。如这2张牌之和不为10的整数倍,则去掉十位数之后个位数为几,则成为“牛几”牌型。
如任意三张牌组合的点数之和都不能成为10的倍数,则称之为“无牛”牌型。
例如:

牛牛牌型:选取的3张牌之和为10的整数倍,余下2张牌之和也为10的整数倍。例:A,9,10,J,Q.选取(A,9,J)和为10的整数倍,(10,Q构成)牛牛

牛九牌型:选取的3张牌之和为10的整数倍,余下2张牌之和的个位数为9。例:A,9,10,J,9。

牛八牌型:选取的3张牌之和为10的整数倍,余下2张牌之和的个位数为8。例:A,9,10,J,8。

牛七牌型:选取的3张牌之和为10的整数倍,余下2张牌之和的个位数为7。例:A,9,10,J,7。选取(A,9,J)和为10的整数倍,(10,7构成)牛七

无牛牌型: 任意选取的3张牌之和均不可能为10的整数倍例:A,9,8,9,7。

JM会打麻将,但是不怎么会斗牛,想请你帮忙编写程序帮忙计算一下,JM 拿到的牌是什么牌型。

输入
输入一行包含5个字符,表示5张牌。

输出
输出一行表示牌型。数字1~9表示牛一至牛九,如果是牛牛牌型,则输出“so cool!”,如果是无牛排序,则输出“so sad!”

//234 MS	16284 KB 枚举哈
import java.util.Scanner;
public class Main{
	public static int ans=0,cnt=0;
	public static void main(String[]args) {
		int a[]=new int[5];
		Scanner sc=new Scanner(System.in);
		String s=sc.nextLine();
		String s1[]=s.split(" ");
		for(int i=0;i<5;i++) {
			char b=s1[i].charAt(0);
			if(b=='A') {
				a[i]=1;
			}else if(b>='2'&& b<='9') {
				a[i]=b-'0';
			}else {
				a[i]=10;
			}
			cnt+=a[i];
		}
		int f1=0;
		for(int i=0;i<5;i++) {
			for(int j=0;j<5;j++) {
				if(i==j) continue;
				for(int k=0;k<5;k++) {
					if(k==i||k==j) continue;
					int sum=a[i]+a[j]+a[k];
					int b=cnt-sum;
					if(sum%10==0 && b%10==0) {
						System.out.println("so cool!");
						return ;
					}else if(sum%10==0) {
						f1=cnt%10;
					}
				}
			}
		}
		if(f1!=0)
			System.out.println(f1);
		else {
			System.out.println("so sad!");
		}
	}
}

G. 试题G:JM boy 去爬山 18’

描述
疫情终于终于得到了一定的控制~
JM boy在家宅了又宅,宅了又宅,总算是可以带上口罩出去爬山运动了~
JM boy在爬完山之后,发现自己爬的山像及了一个数列。山是有山峰山谷的,而数列也是可以定义山峰山谷的。

例如,对于某n个数的一种排列,如果不存在任意的i使得Ai>A(i+1)<A(i+2),则称该种排列为山峰排列。
JM boy想知道,对于1……n的n个数的数列,该数列有多少种排列是属于山峰排列的。

当然,对于n=1及n=2的情况,肯定是所有的排列都属于山峰排列了。
输入
输入一个整数n,表示数列元素的个数。
输出
输出山峰排列的个数。

import java.util.Scanner;
public class Main{
	public static long qpow(long a,long b){
		long ans=1;
		while(b>0){
			if(b%2==0) ans*=a;
			a=a*a;
			b>>=1;
		}
		return ans;
	}
	public static void main(String[]args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		System.out.println(1l<<(n-1));//1
		System.out.println(qpow(2,n-1));//2.快速幂
	}
}
  • 解析:

山峰数列只有四种形状.
在这里插入图片描述
添加的话每一种形状只能添加两个位置.
在这里插入图片描述
每新进一个数,前面形成的队列每一个形状只能加在最顶端的端点的两边.
所以第I个数形成的山峰队列有:a[i]=a[i-1]*2;

  • 正解嘛是全排列,可以自己想一想,差不多滴

H. 试题H:宝剑锋从磨砺出 20’

描述
幸运的wlxsq偶得一块上古神铁!wlxsq决定将其锻造成一把攻击力不小于K的神器!
wlxsq跋山涉水,耗费巨资请来了锻造大师JM boy,在JM boy的手上,任何材料都能发挥到最大价值~
wlxsq同样耗费巨资提前准备了N个材料。每一次对上古神铁进行锻造都需要选择一个材料配合进行锻造。对于每一个材料i,有两种方式能够配合上古神铁进行锻造:
1、材料i作为辅助,配合三味真火进行锻造,可增加攻击力P1 ,材料i可重复使用。

2、材料i直接和上古神铁融合,增加攻击力P2. ,融合后材料i则不能再被使用了。
由于锻造大师JM boy锻造神器是通过锻造次数来收取费用的。由于wlxsq之前的耗费巨资,导致现在wlxsq资金紧张,wlxsq想知道,他最少需要请JM boy锻造几次,才能够把锻造出攻击力不小于K的一把神兵利器,你能帮帮wlxsq吗?

输入
第一行输入两个整数N,K,分别表示材料的个数以及攻击力K。
接下来输入N行,每行两个数Pi1, Pi2 ,表示每个材料对应的方式1,方式2所能够代来的攻击力提升。

输出
输出最少锻造次数
题解:
考虑贪心。
答案一定是选一些方式1和一些方式2构成的。
那么如果确定了选择方式1和方式2的个数,那么我们一定会选择方式1中权值最大的那个值,以及方式2中权值前k的值之和。
所以,我们将所有方式1从大到小排序,所有方式2从大到小排序。
枚举即可。
复杂度O(nlogn)

import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class Main{
	public static void main(String[]args) {
		Scanner sc=new Scanner(System.in);
		int N=sc.nextInt();
		int K=sc.nextInt();
		int []a=new int[N];
		int []b=new int [N];
		for(int i=0;i<N;i++) {
			a[i]=sc.nextInt();
			b[i]=sc.nextInt();
		}
		Arrays.sort(a);
		Arrays.sort(b);
		int ans=0;
		int i=N;
		while(i-->0) {
			if(b[i]>=a[N-1]) {//如果融合的大于锻造的,就先融合
				ans++;
				K-=b[i];
			}else break;//否则的话就后续一直用融合的.
			if(K<=0) break;
		}
		while(K>0) {
			K-=a[N-1];
			ans++;
		}
		System.out.println(ans);
	}
}

再贴上一份我的错误代码吧~

import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;
public class Main{
	public static int ans=0,cnt=0,l=0;
	public static void main(String[]args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int k=sc.nextInt();
		boolean []vis=new boolean [n];
		int ma=0,num=0;
		int a[]=new int[n];
		int b;
		for(int i=0;i<n;i++) {
			b=sc.nextInt();
			a[i]=sc.nextInt();
			if(b>ma) {
				ma=b;
				num=a[i];
				l++;
			}
		}
		Arrays.sort(a);
		for(int i=n-1;i>=0;i--) {
			if(num==a[i]) l--;
			if(a[i]<=ma ||(num==a[i]&& l<1)) {
				break;
			}
			k-=a[i];
			cnt++;
		}
		int h=0;
		if((k-num)%ma!=0 &&k-num>0) ans=1;
		cnt=Math.min(cnt+k/ma+k%ma,cnt+Math.max(k-num,0)/ma+1+ans);
		System.out.println(cnt);
	}
}

再看一遍代码确实当时写的时候钻了牛角尖.菜鸟的痛苦啊 ~ ~ 但我现在其实还是有些不明白,为什么两种方式不用建立一种联系,万一先融和的有锻造最大值的那一种材料呢?我好像也没有看到规定P1一定小于P2.~~

I. 试题I:美味糖果 25’

描述
由于疫情缘故,wlxsq家里还剩下超多年货,没有吃完。

为了简化问题,假设wlxsq家里还剩N种年货,每种年货Ai包,同一种年货中每一包都是一样的。

现在wlxsq准备返杭了,他想从N种年货中挑不超过K包年货带返杭。wlxsq想知道他总共有多少种选择方案?
对于40%的数据,2<=N<=10,
对于100%的数据,2<=N<=1000,Ai,K<=10^5
输入
第一行输入两个整数N,K,含义如题目描述。
第二含输入N个整数 Ai,表示每一种年货的数量。
输出
输出总共方案数,结果对998244353取模。
样例
输入复制
3 1
2 2 2
输出复制
4
输入复制
8 13
1 2 3 4 5 6 7 8
输出复制
65044
【样例1解释】 总共有4种方案,对应每一种年货的选择如下:(1,0,0),(0,1,0),(0,0,1),(0,0,0)
在这里插入图片描述

import java.util.Scanner;
public class Main {
	public static int sub(int x,int y) {
		x-=y;
		if(x<0) x+=m;
		return x;
	}
	public static int add(int x,int y) {
		x+=y;
		if(x>=m) x-=m;
		return x;
	}
	public static int m=998244353;
	public static void main(String[]args) {
		Scanner sc=new Scanner(System.in);
		int [][]dp=new int[2][100005];
		int n=sc.nextInt();
		int k=sc.nextInt();
		int []a=new int[n+1];
		for(int i=1;i<=n;i++) {
			a[i]=sc.nextInt();
		}
		dp[0][0]=1;
		for(int i=1;i<=n;i++) {
			dp[i&1][0]=1;
			for(int j=1;j<=k;j++) {
				if(j>a[i]) {
					int cur=dp[~i&1][j];
					cur=sub(cur,dp[~i&1][j-a[i]-1]);
					cur=add(cur,dp[i&1][j-1]);
					dp[i&1][j]=cur;
				}else {
					int cur=dp[i&1][j-1];
					cur=add(cur,dp[~i&1][j]);
					dp[i&1][j]=cur;
				}
			}
		}
		int ans=0;
		for(int i=0;i<=k;i++) {
			ans=add(ans,dp[n&1][i]);
		}
		System.out.println(ans);
	}
}

J. 试题J:梅深不见冬25’

描述
Let’s have some music结合音乐做此题,效果更佳《梅深不见冬》
风,吹起梅岭的深冬;霜,如惊涛一样汹涌;雪,飘落后把所有烧成空,
像这场,捕捉不到的梦。
醒来时已是多年之久,宫门铜环才长了铁锈,
也开始生出离愁。
——银临《梅深不见冬》
wlxsq在深冬的梅岭中走着,感到十分寒冷,也感到十分孤独。这时他看到前方有一座小屋,透过窗户,他看见里面有一座火炉.正巧,屋内的主人在家里。wlxsq想要进屋内暖和暖和。于是,他敲了敲门,主人热情的开了门。
wlxsq:您好,我能进您屋内取取暖吗?
主人:好的。但是我有一个条件。
wlxsq:什么条件?
在这里插入图片描述
所以,wlxsq希望你能帮他解决这个尘封多年无人可解的难题,如果你做出来了,他将会赏你2147483648 mod 1024块RMB的。
输入
输入两个数n和k。
输出
输出答案,答案对998244353取模。具体输出内容见题目描述。
在这里插入图片描述
在这里插入图片描述
样例输入
【样例1】
5 1
【样例2】
5 2
【样例3】
5 10
【样例4】
8 8
【样例5】
10 10
输出
【样例1】
15
【样例2】
37
【样例3】
9766657
【样例4】
16843792
【样例5】
27446359
提示
我们规定:gcd表示的是最大公约数,gcd(x)=x,gcd(x,y,z)=d表示x,y和z的最大公约数为d,以此类推。
数据范围
子任务1(2分),满足k=1, 1≤n≤10 ^3;
子任务2(3分),满足k=1, 1≤n≤10 ^9;
子任务3(3分),满足k=2, 1≤n≤10^3;
子任务4(3分),满足k≤5, 1≤n≤10;
子任务5(4分),满足k≤ 10^ 3,1≤n≤10^3 ;
子任务6(4分),满足k≤10 ^18 , 1≤n≤10 ^9 ;
子任务7(6分),满足k≤10 ^18 , 1≤n≤10 ^10;

  • 下面贴上大佬的代码,等以后水平够了再来研究研究~~
// Author: wlzhouzhuan
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define ull unsigned long long
#define rint register int
#define rep(i, l, r) for (rint i = l; i <= r; i++)
#define per(i, l, r) for (rint i = l; i >= r; i--)
#define mset(s, _) memset(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define mp(a, b) make_pair(a, b)

inline int read() {
  int x = 0, neg = 1; char op = getchar();
  while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); }
  while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); }
  return neg * x;
}
inline void print(int x) {
  if (x < 0) { putchar('-'); x = -x; }
  if (x >= 10) print(x / 10);
  putchar(x % 10 + '0');
}

const ll mod = 998244353;
const int N = 3000002;
ll qpow(ll a, ll b) {
  ll res = 1;
  while (b > 0) {
    if (b & 1) res = res * a % mod;
    a = a * a % mod;
    b >>= 1;
  }
  return res;
}

bitset <N> vis;
int pr[N >> 1], l;
ll phi[N];
ll n, k, L;
inline void pre(int n) {
  //cerr << "debug: " << n << '\n';
  phi[1] = 1;
  for (rint i = 2; i <= n; i++) {
    if (!vis[i]) pr[l++] = i, phi[i] = i - 1;
    for (rint j = 0; j < l && pr[j] * i <= n; j++) {
      int v = pr[j]; vis[v * i] = 1;
      if (i % v == 0) {
        phi[i * v] = phi[i] * v;
        break;
      }
      phi[i * v] = phi[i] * (v - 1);
    }
  }
  for (rint i = 1; i <= n; i++) phi[i] = (phi[i] + phi[i - 1]) % mod;
}

unordered_map <ll, ll> Map;
ll S(ll n) {
  if (n <= L) return phi[n];
  if (Map[n]) return Map[n];
  ll res = n * (n + 1) / 2 % mod;
  for (ll i = 2, j; i <= n; i = j + 1) {
    j = n / (n / i);
    res = (res + mod - (j - i + 1) * S(n / i) % mod) % mod;
  }
  if (res < 0) res += mod;
  return Map[n] = res;
}
ll solve(ll n, ll k) {
  ll lst = 0, now = 0, ans = 0; k %= (mod - 1);
  for (ll i = 1, j; i <= n; i = j + 1) {
    j = n / (n / i);
    now = (S(j) % mod + mod) % mod;
    //printf("lst = %lld, now = %lld\n", lst, now);
    //printf(">> %lld %lld\n", i, j);
    ans = (ans + qpow(n / i, k) * (now - lst + mod) % mod) % mod;
    lst = now;
  }
  return ans;
}

int main() {
  scanf("%lld%lld", &n, &k);
  //L = n; pre(L);
  L = pow(n, 2.0 / 3); pre(L);
  printf("%lld\n", solve(n, k));
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值