bjfu1211 推公式,筛素数
题目是求fun(n)的值
fun(n)= Gcd(3)+Gcd(4)+…+Gcd(i)+…+Gcd(n).
Gcd(n)=gcd(C[n][1],C[n][2],……,C[n][n-1])
C[n][k] means the number of way to choose k things from n things.
n最大一百万,马上反映到可能是递推打表。
首先肯定是推公式了,fun(n)其实就是Gcd(n)的一个前n项和,没意义,直接看Gcd(n),把前几项列出来,发现公式是Gcd(n) = lcm(1,……,n-1,n)/lcm(1,……,n-1),其中lcm是求若干个数的最小公倍数。例如Gcd(1)=lcm(1)=1, Gcd(2)=lcm(1,2)/lcm(1)=2,
Gcd(6)=lcm(1,2,3,4,5,6)/lcm(1,2,3,4,5)=60/60=1
于是我马上想到了方法,先筛法打出一百万以内的素数表,然后从lcm(1,2)开始逐个往后递推lcm(1,……,n-1,n),开一个数组来表示其值(数组每一位表示某个素数,值表示这个素因子的个数)。但是这样的话,递推的时候必须遍历素数表,就算只考虑1000以内的素数,也超过100个,很有可能超时。
不过因为是学弟出的题,本着测试的态度,我按这个思路打了一个,果然超时,看来数据不算太水。
/*
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
using namespace std; #ifdef ON_LOCAL_DEBUG
#else
#endif
typedef long long LL;
const int MAXN = ;
LL ans[MAXN];
int pn, pt[MAXN], num[MAXN];
bool ip[MAXN];
int N = ;
void init_prime_table() {
memset(ip, true, sizeof(ip));
int i;
ip[] = false;
pn = ;
pt[pn++] = ;
for (i = ; i < N; i += ) {
ip[i] = false;
}
for (i = ; i * i <= N; i += ) {
if (!ip[i])
continue;
pt[pn++] = i;
for (int s = * i, j = i * i; j < N; j += s)
ip[j] = false;
}
for (; i < N; i++) {
if (ip[i]) {
pt[pn++] = i;
}
}
}
inline int mypow(int a, int b) {
int ret = ;
while (b--) {
ret *= a;
}
return ret;
} int comput() {
ans[] = ;
for (int i = ; i <= N; i++) {
if (ip[i]) {
num[i]++;
ans[i] = i;
continue;
}
int _gcd = ;
int n = i;
for (int j = ; j < pn; j++) {
if (n == ) {
break;
}
if (n > && ip[n]) {
break;
}
int t = ;
while (n % pt[j] == ) {
t++;
n = n / pt[j];
}
if (t > num[pt[j]]) {
_gcd *= mypow(pt[j], t - num[pt[j]]);
num[pt[j]] = t;
}
}
ans[i] = _gcd;
}
for (int i = ; i < MAXN; i++) {
ans[i] += ans[i - ];
}
return ;
} int main() {
#ifdef ON_LOCAL_DEBUG
freopen("data.in", "r", stdin);
#endif
int n;
// get_prime_table(MAXN);
init_prime_table();
// pn = pt.size();
memset(num, , sizeof(num));
comput();
while (scanf("%d", &n) == ) {
printf("%I64d\n", ans[n]);
}
return ;
}
下面是正解。正解的方法对上面那种方法的改进类似于筛法对普通求素数法的改进。原来的方法这么工作:比如在递推到n=8的时候,发现8有三个素因子2,而之前的lcm里只有两个素因子2,所以这次的值会再乘一个2。那么新方法直接倒过来,当递推到2的时候,发现2是素数,那么就把2^2,2^3,2^4等等的ans里都预先乘上一个2。这样就避免了遍历素数表,降低了复杂度,而且代码更为简洁。代码如下:
/*
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
using namespace std; #ifdef ON_LOCAL_DEBUG
#else
#endif
typedef long long LL;
const int MAXN = ;
LL ans[MAXN];
int pn, pt[MAXN];
bool ip[MAXN];
int N = MAXN;
void init_prime_table() {
memset(ip, true, sizeof(ip));
int i;
ip[] = false;
pn = ;
pt[pn++] = ;
for (i = ; i < N; i += ) {
ip[i] = false;
}
for (i = ; i * i <= N; i += ) {
if (!ip[i])
continue;
pt[pn++] = i;
for (int s = * i, j = i * i; j < N; j += s)
ip[j] = false;
}
for (; i < N; i++) {
if (ip[i]) {
pt[pn++] = i;
}
}
} int comput() {
fill(ans, ans + N + , );
for (int i = ; i <= N; i++) {
if (ip[i]) {
LL t = i;
while (t <= N) {
ans[t] *= i;
t *= i;
}
}
}
for (int i = ; i < MAXN; i++) {
ans[i] += ans[i - ];
}
return ;
} int main() {
#ifdef ON_LOCAL_DEBUG
// freopen("test.in", "r", stdin);
// freopen("data.out", "w", stdout);
freopen("data.in", "r", stdin);
#endif
int n;
init_prime_table();
comput();
while (scanf("%d", &n) == ) {
printf("%I64d\n", ans[n]);
}
return ;
}
bjfu1211 推公式,筛素数的更多相关文章
- 【板子】gcd、exgcd、乘法逆元、快速幂、快速乘、筛素数、快速求逆元、组合数
1.gcd int gcd(int a,int b){ return b?gcd(b,a%b):a; } 2.扩展gcd )extend great common divisor ll exgcd(l ...
- ACM-ICPC 2018 南京赛区网络预赛 J题Sum(线性筛素数)
题目链接:https://nanti.jisuanke.com/t/30999 参考自博客:https://kuangbin.github.io/2018/09/01/2018-ACM-ICPC-Na ...
- codeforces 185A Plant(推公式)
Plant [题目链接]Plant [题目类型]推公式 &题解: 这个是可以推公式的: 每年的总个数是4^n个,设n年时向上的个数是x个,向下的个数是y个,那么n+1年时,向上的个数是3* x ...
- 欧拉函数O(sqrt(n))与欧拉线性筛素数O(n)总结
欧拉函数: 对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目. POJ 2407.Relatives-欧拉函数 代码O(sqrt(n)): ll euler(ll n){ ll ans=n; ...
- 全网一定不是最好懂的C++线性筛素数
Part 0:概念 先给几个概念(很重要): 合数:如果\(xy=z\text{且}x,y\text{为正整数}\),我们就说\(x,y\text{是}z\text{的合数}\) 素数:如果数\(a\ ...
- CF449C Jzzhu and Apples (筛素数 数论?
Codeforces Round #257 (Div. 1) C Codeforces Round #257 (Div. 1) E CF450E C. Jzzhu and Apples time li ...
- HDU 4873 ZCC Loves Intersection(JAVA、大数、推公式)
在一个D维空间,只有整点,点的每个维度的值是0~n-1 .现每秒生成D条线段,第i条线段与第i维度的轴平行.问D条线段的相交期望. 生成线段[a1,a2]的方法(假设该线段为第i条,即与第i维度的轴平 ...
- HDU 4870 Rating(概率、期望、推公式) && ZOJ 3415 Zhou Yu
其实zoj 3415不是应该叫Yu Zhou吗...碰到ZOJ 3415之后用了第二个参考网址的方法去求通项,然后这次碰到4870不会搞.参考了chanme的,然后重新把周瑜跟排名都反复推导(不是推倒 ...
- 洛谷P3383 【模板】线性筛素数
P3383 [模板]线性筛素数 256通过 579提交 题目提供者HansBug 标签 难度普及- 提交 讨论 题解 最新讨论 Too many or Too few lines 样例解释有问题 ...
随机推荐
- Mysql 1030 Got error -1 from storage engine 错误解决
检查你的my.cnf或my.ini,里面会有一个参数innodb_force_recovery,你看看他的值,默认是没有这个参数,没有的话,他的默认值是0,这个参数的值如果大于0,innodb会被禁止 ...
- floodlight 中两个互相矛盾的地方
floodlight中,添加防火墙规则,0表示最高优先级,数字越大,优先级越低;但是在StaticFlowPusher中写flow的时候,0表示最低优先级,数字越大,优先级越高,32767为最高. f ...
- hdu 1005 java(System.out.println();与System.out.println(“\n”);)
//package Main; import java.util.Scanner; public class Main { static int [][] mat=new int [2][2]; st ...
- spring中的aware接口
1.实现了相应的aware接口,这个类就获取了相应的资源. 2.spring中有很多aware接口,包括applicationContextAware接口,和BeanNameAware接口. 实现了这 ...
- 转载CSDN (MVC WebAPI 三层分布式框架开发)
前言:SOA(面向服务的架构)是目前企业应用开发过程中普遍采用的技术,基于MVC WebAPI三层分布式框架开发,以此适用于企业信息系统的业务处理,是本文论述的重点.此外,插件技术的应用,富客户端JQ ...
- Android 多线程断点下载
package com.itheima.mutiledownloader; import java.io.BufferedReader; import java.io.File; import jav ...
- 基于条件随机场(CRF)的命名实体识别
很久前做过一个命名实体识别的模块,现在有时间,记录一下. 一.要识别的对象 人名.地名.机构名 二.主要方法 1.使用CRF模型进行识别(识别对象都是最基础的序列,所以使用了好评率较高的序列识别算法C ...
- 初学者的checklist:对于QTP,你应该知道的9个基本概念
学习QTP或者其他相关任何工具的方法都是首先把基本的概念过一遍.正所谓砍柴不怕磨刀功,一旦你对这些概念熟悉了,你就可以学习该工具的高级部分了.写这篇文章的目标是列出初学QTP的人应该掌握的所有基本概念 ...
- Cookie的具体使用之来存储对象
1.创建一个新的cookie,并赋值. HttpCookie cookie; cookie=new HttpCookie("user"); cookie.D ...
- 爬虫技术(五)-- 模拟简单浏览器(附c#代码)
由于最近在做毕业设计,需要用到一些简单的浏览器功能,于是学习了一下,顺便写篇博客~~大牛请勿喷,菜鸟练练手~ 实现界面如下:(简单朴素版@_@||) button_go实现如下: private vo ...