[acdream_oj1732]求1到n的最小公倍数(n<=1e8)
题意:如标题
思路:如果n在10^6以内则可以用o(nlogn)的暴力,题目给定的是n<=1e8,暴力显然是不行的,考虑到1到n的最小公倍数可以写成2^p1*3^p2*5^p3*...这种素数的幂的乘积形式,对于当前询问n,可知质数x的指数为(int)log(x,n)(因为要满足是公倍数且最小),因为前n个数有n/logn个质数,这样一次处理为o(n/logn*logn) = o(n)的。由于有T组测试数据,直接T次处理肯定会超时,需要离线处理。具体怎么操作呢?首先将T个询问按n从小到大排序,从小到大处理时,每个质数的指数是非递减的,所以只需在上一次的答案上乘以若干质数。如果记录上一个询问后的每个质数的指数,然后遍历所有质数,看质数有没有增加,这样的时间复杂度为o(T*n/logn+n/logn*logn)=o(Tn/logn),跟直接T次在线处理没什么两样,原因是有很多的质数的指数并不会变化,却也被访问了一次。
一种解决办法是预先计算出每个询问n所增加的质数,从小到大枚举每个质数的每个幂,然后在T个询问中二分,得到第一次出现这个幂的n,这样时间复杂度为o(n/logn*logn*logT)=o(nlogT),查询时就相当于是只查了那个最大的n一样,所以查询复杂度为o(n),总复杂度为o(nlogT),虽然过不了此题,但这个思路却可以对付一些其他T比较大,n稍小的数据。
下面讲另一种o(Tsqrt(n)+n)的思路:核心思想是将质数分为两类,一类是小于等于sqrt(n),一类大于sqrt(n),不难发现对于第二类质数,它们的质数要么是1要么是0,也就是说,对于第二类质数,假设它在某个询问n时加进了答案,那么在以后的询问中就不用再考虑了(如果继续加进答案,那么它的指数会超过1),于是不难得到如下算法:对每个询问,枚举第一类质数,判断他们的质数有没有增加(实际操作时用试乘法而不是求一个对数),而第二类质数只需维护当前乘到了哪个质数就行了。下面是代码:
#pragma comment(linker, "/STACK:10240000,10240000") #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility> using namespace std; #define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define define_m int m = (l + r) >> 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a) typedef unsigned int uint;
typedef long long LL;
typedef pair<int, int> pii;
typedef vector<int> vi; const int dx[] = {, , -, , , , -, -};
const int dy[] = {-, , , , , -, , - };
const int maxn = 1e8 + ;
const int md = ;
const int inf = 1e9 + ;
const LL inf_L = 1e18 + ;
const double pi = acos(-1.0);
const double eps = 1e-; template<class T>T gcd(T a, T b){return b==?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; } int vis[];
unsigned int prime[]; int c; void init() {
const int t = 1e8 + ;
for (int i = ; i <= t; i ++) {
int u = i >> , v = i & ;
if (vis[u] & ( << v)) continue;
prime[c ++] = i;
if ((LL)i * i > t) continue;
for (int j = i * i; j <= t; j += i) {
int u = j >> , v = j & ;
vis[u] |= << v;
}
}
} pii node[];
unsigned int out[];
const int max_sq = 1e4;
unsigned int last[]; int main() {
//freopen("in.txt", "r", stdin);
int T, cas;
cin >> T;
cas = T;
init();
while (T --) {
int n;
sint(n);
node[cas - T - ] = make_pair(n, cas - T - );
}
sort(node, node + cas);
unsigned int ans = ;
int n = node[].first;
int cur = ;
for (int i = ; prime[i] < max_sq; i ++) last[i] = ;
rep_up0(i, cas) {
int n = node[i].first;
for (int j = ; prime[j] < max_sq; j ++) {
while ((LL)last[j] * prime[j] <= n) {
last[j] *= prime[j];
ans *= prime[j];
}
}
while (prime[cur] <= n) {
cur ++;
if (prime[cur - ] < max_sq) continue;
ans *= prime[cur - ];
}
out[node[i].second] = ans;
}
rep_up0(i, cas) cout << out[i] << endl;
return ;
}
18U93ZOWB.gif)
[acdream_oj1732]求1到n的最小公倍数(n<=1e8)的更多相关文章
- 算法 - 求两个自然数的最小公倍数(C++)
//************************************************************************************************** ...
- C# 求俩个正整数的最小公倍数和最大公约数
C# 求俩个正整数的最小公倍数和最大公约数 1.公倍数.最小公倍数 两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数 翻开小学5年级下册PPT 1.1 ...
- 代码代码:输入两个正整数m和n,求其最大公约数和最小公倍数。15 20 5
import java.util.Scanner; //输入两个正整数m和n,求其最大公约数和最小公倍数.15 20 5 public class Test { public static void ...
- Python实现利用最大公约数求三个正整数的最小公倍数示例
Python实现利用最大公约数求三个正整数的最小公倍数示例 本文实例讲述了Python实现利用最大公约数求三个正整数的最小公倍数.分享给大家供大家参考,具体如下: 在求解两个数的小公倍数的方法时,假设 ...
- java求最大公约数,和最小公倍数
import java.util.Scanner; public class Test { public static void main(String[] args) { Scanner sc = ...
- JS求一个数组元素的最小公倍数
求几个数的最小公倍数就是先求出前两个数的最小公倍数,然后再把这个最小公倍数跟第三个数放在一起来求最小公倍数,如此类推... var dbList = []; //两个数的最小公倍数 function ...
- vjudge 最大公约数GCD 直接求最大共约束和最小公倍数的指令
原题链接https://vjudge.net/contest/331993#problem/C 输入2个正整数A,B,求A与B的最大公约数. Input2个数A,B,中间用空格隔开.(1<= A ...
- 辗转相除 求最大公约数!or 最小公倍数
求最大公约数和最小公倍数的经典算法--辗转相除法描述如下: 若要求a,b两数的最大公约数和最小公倍数,令a为a.b中较大数,b为较小数,算法进一步流程: while(b不为0) { temp=a%b: ...
- 输入两个正整数m和n,求其最大公约数和最小公倍数
public static void main(String[] args){ Scanner sc = new Scanner (System.in); int a,b; System.out ...
随机推荐
- PHP修改脚本最大执行时间和最大内存限制
PHP设置脚本最大执行时间的三种方法 1.在php.ini里面设置 max_execution_time = 120; 2.通过PHP的ini_set函数设置 ini_set("max_ex ...
- 【错误】python百分号冲突not enough arguments for format string
query = "SELECT * FROM devices WHERE devices.`id` LIKE '%{}%'".format("f2333") d ...
- python的历史和下载python解释器
一.python的诞生 1.Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,创造了一种C和sh ...
- BUUOJ [WUSTCTF2020]朴实无华
[WUSTCTF2020]朴实无华 复现了武科大的一道题/// 进入界面 一个hack me 好吧,直接看看有没有robot.txt 哦豁,还真有 好吧 fAke_f1agggg.php 看了里面,然 ...
- Jmeter与LoadRunner的比较
一.与Loadrunner的比较相似点 1.Jmeter的架构跟loadrunner原理一样, 都是通过中间代理,监控&收集并发客户端发现的指令,把他们生成脚本,再发送到应用服务器,再监控服务 ...
- Python开发基础之Python常用的数据类型
一.Python介绍 Python是一种动态解释型的编程语言.Python它简单易学.功能强大.支持面向对象.函数式编程,可以在Windows.Linux等多种操作系统上使用,同时Python可以在J ...
- elementaryos5安装chrome,修复依赖
1.首先去下载个chrome:https://www.google.cn/chrome/ 2.尝试安装chrome:sudo dpkg -i google-chrome-stable_current_ ...
- Qt 正则表达式检查 IP 格式
KillerSmath 2018年6月29日 下午10:41 @Pranit-Patil Hi there. Like @jonB says above, you should to replace\ ...
- Inno Setup 添加版权信息
[Setup]AppCopyright=Copyright (C) - My Company, Inc. 有以上一句,即可在右键 --> Property --> Details 里看见版 ...
- Github C 编译器项目 8cc main函数中用到的 C库函数
atexit C 库函数 int atexit(void (*func)(void)) 当程序正常终止时,调用指定的函数 func.您可以在任何地方注册你的终止函数,但它会在程序终止的时候被调用. s ...