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, ...
随机推荐
- phonegap + Framework7 之 ios 推送跳转测试
先说说项目情况:使用phonegap创建的ios项目,然后在使用html + css开发网页中又使用了一个框架Framework7(Framework7是一个构建仿原生ios和android应用的框架 ...
- iOS 单例模式 浅叙
单例模式作用 可以保证在程序运行过程中,一个类只有一个实例,而且该实例易于供外界使用 从而方便地控制了实例个数,并节约系统资源 单例模式使用场合 在整个引用程序中,共享一份资源(这份资源只需要创建初始 ...
- 【代码笔记】iOS-iCarouselDemo
一,效果图. 二,工程图. 三,代码. RootViewController.h RootViewController.m myCell.h #import <UIKit/UIKit.h> ...
- 【代码笔记】iOS-仿QQ空间,歌曲播放
一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> #import <AVFoundation/AVFo ...
- iOS开发之JSON格式数据的生成与解析
本文将从四个方面对IOS开发中JSON格式数据的生成与解析进行讲解: 一.JSON是什么? 二.我们为什么要用JSON格式的数据? 三.如何生成JSON格式的数据? 四.如何解析JSON格式的数据? ...
- android 多线程下载 断点续传
来源:网易云课堂Android极客班第八次作业练习 练习内容: 多线程 asyncTask handler 多线程下载的原理 首先获取到目标文件的大小,然后在磁盘上申请一块空间用于保存目标文件,接着把 ...
- C#复习⑤
C#复习⑤ 2016年6月19日 22:39 Main Inheritance 继承 1.继承的语法结构 class A { // base class int a; public A() {...} ...
- PreferenceScreen监听子项的刷新
有个PreferenceScreen,他有一些个子项目.它的Summary需要根据子项的设置来改变的,所以需要监听子项的刷新事件. preferenceScreen.setOnPreferenceCh ...
- 走进云背后:微软Azure web 项目通过web service部署web site
探索云那不为人知的故事(一):Web Services部署web site 前奏:Windows Azure是微软基于云计算的操作系统,现在更名为“Microsoft Azure”,和Azure Se ...
- Iframe指定页面,并使其与该页面显示一致
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...