O(1) 查询gcd
我们来安利一个黑科技。(其实是Claris安利来的
比如我现在有一坨询问,每次询问两个不超过n的数的gcd。
n大概1kw,询问大概300w(怎么输入就不是我的事了,大不了交互库
http://mimuw.edu.pl/~kociumaka/files/stacs2013_slides.pdf
http://drops.dagstuhl.de/opus/volltexte/2013/3938/pdf/26.pdf
我们定义一个数k的一种因式分解k=k1*k2*k3为“迷之分解”当且仅当k1、k2、k3为质数或小于等于$\sqrt{k}$ 。
我们发现线筛的时候对于一个数x,设x最小的质因子为p,x/p=g,那么x的“迷之分解”可以通过g的“迷之分解”中三个数最小的一个乘上p得到。
证明似乎可以用数学归纳法证(然而我证不出来啊
然后对于每两个小于等于$\sqrt{n}$ 的数我们可以打一张gcd表出来。
最后如果我们要询问gcd(x,y),我们找到x的“迷之分解”,然后如果分解的一部分小于等于$\sqrt{n}$ 那就查表,否则那就是一个质数,分类讨论一下就行了。
伪代码:

UPD:实际测试了一下随机数据跑得并没有沙茶gcd快。可能是我实现的姿势不够优越(雾
大家可以测试一下跑gcd(5702887,9227465)这个算法比沙茶gcd不知道快到哪里去了
//跑得比谁都快的gcd?
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <time.h>
#include <limits>
#include <set>
#include <map>
using namespace std;
const int N=;
const int sn=sqrt(N);
bool np[N+];
int ps[N+],pn=;
int cs[N+][];
void xs()
{
np[]=cs[][]=cs[][]=cs[][]=;
for(int i=;i<=N;i++)
{
if(!np[i]) {cs[i][]=cs[i][]=; cs[i][]=i; ps[++pn]=i;}
for(int j=;j<=pn&&i*ps[j]<=N;j++)
{
np[i*ps[j]]=;
int cm=cs[i][]*ps[j];
if(cm<cs[i][])
{
cs[i*ps[j]][]=cm;
cs[i*ps[j]][]=cs[i][];
cs[i*ps[j]][]=cs[i][];
}
else if(cm<cs[i][])
{
cs[i*ps[j]][]=cs[i][];
cs[i*ps[j]][]=cm;
cs[i*ps[j]][]=cs[i][];
}
else
{
cs[i*ps[j]][]=cs[i][];
cs[i*ps[j]][]=cs[i][];
cs[i*ps[j]][]=cm;
}
if(i%ps[j]);else break;
}
}
}
int gcdd[sn+][sn+];
void smgcd()
{
for(int i=;i<=sn;i++) gcdd[i][]=gcdd[][i]=i;
for(int i=;i<=sn;i++)
{
for(int j=;j<=i;j++) gcdd[i][j]=gcdd[j][i]=gcdd[i-j][j];
}
}
void pre_gcd() {xs(); smgcd();}
int gcd(int a,int b)
{
if(a>N||b>N)
{
puts("Fuck You\n");
return -;
}
int *x=cs[a],g=;
for(int i=;i<;i++)
{
int d;
if(x[i]<=sn) d=gcdd[x[i]][b%x[i]];
else if(b%x[i]) d=;
else d=x[i];
g*=d; b/=d;
}
return g;
}
int euclid_gcd(int x,int y)
{
while(y)
{
int t=x%y; x=y; y=t;
}
return x;
}
int tmd=-;
void gc()
{
if(tmd==-) tmd=clock();
else
{
printf("Passed: %dms\n",clock()-tmd);
tmd=-;
}
}
int main()
{
int seed=time();
//1kw个随机数测试
int ans;
printf("Euclid gcd...\n");
srand(seed);
gc();
ans=;
for(int i=;i<=;i++)
{
int a=(rand()*+rand())%N+,b=(rand()*+rand())%N+;
ans^=euclid_gcd(a,b);
}
printf("Ans = %d\n",ans);
gc();
printf("New gcd...\n");
srand(seed);
gc();
pre_gcd();
ans=;
for(int i=;i<=;i++)
{
int a=(rand()*+rand())%N+,b=(rand()*+rand())%N+;
ans^=gcd(a,b);
}
printf("Ans = %d\n",ans);
gc();
}
O(1) 查询gcd的更多相关文章
- HDU 5726 GCD
传送门 GCD Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem ...
- Codeforces 914D - Bash and a Tough Math Puzzle 线段树,区间GCD
题意: 两个操作, 单点修改 询问一段区间是否能在至多一次修改后,使得区间$GCD$等于$X$ 题解: 正确思路; 线段树维护区间$GCD$,查询$GCD$的时候记录一共访问了多少个$GCD$不被X整 ...
- 线段树 区间加 gcd 差分 小阳的贝壳
小阳的贝壳 如果线段树要维护区间gcd 这个很简单,但是如果有了区间加,维护gcd 就比较麻烦了. 这个首先可以证明的是 gcd(x,y,z)=gcd(x,y-x,z-y) 这个可以推到 n 个 ...
- 2016 Multi-University Training Contest 1
8/11 2016 Multi-University Training Contest 1 官方题解 老年选手历险记 最小生成树+线性期望 A Abandoned country(BH) 题意: 1. ...
- BZOJ5302 [HAOI2018]奇怪的背包 【数论 + dp】
题目 小 CC 非常擅长背包问题,他有一个奇怪的背包,这个背包有一个参数 PP ,当他 向这个背包内放入若干个物品后,背包的重量是物品总体积对 PP 取模后的结果. 现在小 CC 有 nn 种体积不同 ...
- 树状数组 gcd 查询 Different GCD Subarray Query
Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K ( ...
- 2016暑假多校联合---GCD
Problem Description Give you a sequence of N(N≤100,000) integers : a1,...,an(0<ai≤1000,000,000). ...
- GCD的深入理解
GCD 深入理解(一) 本文由@nixzhu翻译至raywenderlich的<grand-central-dispatch-in-depth-part-1> 虽然 GCD 已经出现过一段 ...
- HDU5726 GCD(二分 + ST表)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5726 Description Give you a sequence of N(N≤100, ...
随机推荐
- TextView显示颜色高亮的问题
TextView textView = (TextView) findViewById( R.id.tv ); String text = "<font color=\"#d ...
- 模态视图的modalTransitionStyle、modalPresentationStyle
1.modalTransitionStyle: 它是使用- (void)presentViewController:(UIViewController *)viewControllerToPresen ...
- unity安卓和IOS读写目录
StreamingAssets文件夹下的只读不可写路径: 安卓读:filePath = Application.streamingAssetsPath + "/文件名.格式名"; ...
- iOS [[NSBundle mainBundle] pathForResource:@"" ofType:@""]无法获取到文件
将一个文件导入到工程中后,用[[NSBundle mainBundle] pathForResource:@"" ofType:@""]来获取到该文件时,一直无 ...
- Git 的 .gitignore 配置
.gitignore 配置文件用于配置不需要加入版本管理的文件,配置好该文件可以为我们的版本管理带来很大的便利,以下是个人对于配置 .gitignore 的一些心得. 1.配置语法: 以斜杠“/”开头 ...
- Git的常用操作,记录下
首先生成密钥 ssh-keygen -t rsa -C "your_email@youremail.com" 然后打开workdir,敲 git init 设置一个远端库 git ...
- Android 自定义Application
在android中 自定义Application 常用的作用是1 保存在程序运行中的全局变量 实例:public class GlobalApp extends Application{ privat ...
- SQL Server:“数据收缩”详解
1. 数据库的相关属性 在MS中创建数据库时会为数据库分配初始的大小(如下图:数据库和日志两个文件),随着数据库的使用文件会逐渐增大.数据库文件大小的增加有两种方式: 自动增长:在自动增长中可以设置每 ...
- 多年前写的DataTable与实体类的转换,已放github
本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 阅读目录 介绍 起因 代码 UnitTest G ...
- HTTPS那些事(二)SSL证书
转自:http://www.guokr.com/post/116169/ 从第一部分HTTPS原理中, 我们可以了解到HTTPS核心的一个部分是数据传输之前的握手,握手过程中确定了数据加密的密码.在握 ...