[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 ;
}
11巨带我飞 [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 ...
随机推荐
- 使用jquery清空input 文本框中的内容
只需要将文本框的值置为空即可: function resetBtn(){ $("#name").val(""); }
- Java 导出Excel xlsx、xls, CSV文件
通用导出功能: 1.支持Excel xlsx.xls 2.支持CSV文件导出 3.数据库查询分页导出.内存导出 4.支持大批量数据导出 使用步骤如下 导入jar <dependency> ...
- webpack之Loader
我们知道webpack的优点之一就是专注于处理模块化的项目,能做到开箱即用,但同时这也是webpack的缺点,只能用于模块化开发的项目,例如:Vue,React,Angular.Webpack在进行打 ...
- s3fs-fuse 把 s3-like 对象存储挂载到本地
s3fs-fuse 是一个采用 c++
- How to permit SSH root Login in Ubuntu 18.04
https://www.ubuntu18.com/ssh-permitrootlogin/ SSH root login is disabled by default in Ubuntu 18.04. ...
- CentOS上安装配置 mongodb
CentOS 首先yum list mongo* 查看是否有关于mongo的安装包,检查后安装即可 mongo 分client端和server端,server启动db服务,client可以连接到s ...
- asList和ArrayList不得不说的故事
目录 简介 创建ArrayList UnsupportedOperationException asList 转换 总结 asList和ArrayList不得不说的故事 简介 提到集合类,ArrayL ...
- HDU 5725 Game
1. 笔记 题意是求距离的期望(距离仍指连接两点且有效的路径长度的最小值).直观想象可以发现,该距离与曼哈顿距离相比最多多2(可以构造这样的路径). 答案=(任意两点曼哈顿距离的总和 - 至少有一点是 ...
- 01-Vue初学习
1. Vue下载 (1)网址:https://cn.vuejs.org/v2/guide/installation.html (2)点击开发版本,下载完成是一个 Vue.js 2. 使用 (1)创建文 ...
- 使用Xamarin开发即时通信系统 -- 基础篇(大量图文讲解 step by step,附源码下载)...
如果是.NET开发人员,想学习手机应用开发(Android和iOS),Xamarin 无疑是最好的选择,编写一次,即可发布到Android和iOS平台,真是利器中的利器啊!而且,Xamarin已经被微 ...