前置知识

下面,先来介绍一下Stern-Brocot Tree的结构:

其是一棵满二叉树,每一个节点都是一个最简分数,其中根为$\frac{1}{1}$

假设前$i$层的中序遍历分数依次为$\frac{y_{i,j}}{x_{i,j}}$(其中$i\ge 1,j\in [1,2^{i})$,即根为第一层),并令$(x_{i,0},y_{i,0})=(1,0)$且$(x_{i,2^{i}},y_{i,2^{i}})=(0,1)$,那么第$i+1$层的从左到右第$j$个分数为$\frac{y_{i,j-1}+y_{i,j}}{x_{i,j-1}+x_{i,j}}$(其中$j\in [1,2^{i}]$)

(特别的,根据定义在$i=0$时,$\{(x_{i},y_{i})\}$即仅包含$(1,0)$和$(0,1)$)

根据定义,不难得到有$f(x_{i})=x_{i+1}$且$f(y_{i})=y_{i+1}$,这可以方便理解下面的结论——

性质1:$\forall i\ge 0,\frac{y_{i,j}}{x_{i,j}}$构成一个严格单调递增的序列(特别的,定义$\frac{1}{0}=\infty$)

性质2:若$x_{i},y_{i}\in N^{*}$,存在$i\ge 0,j\in [0,2^{i})$满足$(x_{i,j},y_{i,j})=(x_{1},y_{1})$且$(x_{i,j+1},y_{i,j+1})=(x_{2},y_{2})$当且仅当$x_{1}y_{2}-x_{2}y_{1}=1$

性质3:若$x,y\in N^{*}$,存在$i\ge 0,j\in [0,2^{i}]$满足$(x_{i,j},y_{i,j})=(x,y)$当且仅当$\gcd(x,y)=1$

性质1和性质2可以归纳得到,性质3可以根据性质2得到,证明过程略

题解

性质4:$\forall i\ge 0,j\in [0,2^{i}]$,有$x_{i,j}+y_{i,j}\ge i+1$

性质5:$\forall i\ge 0,j\in [0,2^{i}]$,有$F^{(i)}(\{a,b\})_{j}=ax_{i,j}+by_{i,j}$

这两个性质同样可以归纳得到,证明过程略

结合性质1和3,不难得到$\{B_{i}\}=\{ax+by\mid x,y\in N^{*},\gcd(x,y)=1$且$ax+by\le N \}$,并且对应的顺序即按照$\frac{y}{x}$从小到大排序,由此即有一个$o(N^{2}\log N)$的暴力做法

考虑优化,不妨假设$\gcd(a,b)=1$(将$N$除以$\gcd(a,b)$即可),那么根据裴蜀定理,存在$ab'-a'b=1$,并根据通解的形式调整使得$a'\in [0,a)$,进而有$b'=\frac{a'b+1}{a}\in [1,b]$

此时,不妨将二元组$(x,y)$变为$(a'x+b'y,ax+by)$,并对条件分析——

性质6:$\gcd(x,y)=\gcd(a'x+b'y,ax+by)$

性质7:$\frac{y_{1}}{x_{1}}<\frac{y_{2}}{x_{2}}$等价于$\frac{a'x_{1}+b'y_{1}}{ax_{1}+by_{1}}<\frac{a'x_{2}+b'y_{2}}{ax_{2}+by_{2}}$

性质6可以归纳并结合辗转相减法得到,性质7直接展开可得,证明过程略

另外,关于$x,y\in N^{*}$的条件,将$x$和$y$用新二元组的$(x,y)$表示,解得即$x,y\in N^{*}$且$\frac{a'}{a}\le \frac{x}{y}\le \frac{b'}{b}$

综上,问题即求分母在$[1,N]$中、值在$[\frac{a'}{a},\frac{b'}{b}]$中的从小到大第$[l,r]$个最简分数(的分母),此时只需要在之前的Stern-Brocot Tree上二分即可

在过程中,即需要查询子树大小,也即求出值在$[\frac{x_{1}}{y_{1}},\frac{x_{2}}{y_{2}}]$中且分母$\in[1,N]$的分数个数

关于这个问题,先将范围差分(即仅考虑$\le \frac{x_{2}}{y_{2}}$),并对$\gcd(x,y)=1$的条件容斥,即令$g(n)$为忽略此条件且分母$\in [1,n]$的分数个数,那么不难得到答案即$\sum_{d=1}^{N}\mu(d)g(\lfloor\frac{N}{d}\rfloor)$

预处理$\mu$的前缀和后,数论分块即变为求$\sqrt{N}$个$g(n)$的值,则有$g(n)=\sum_{y=1}^{n}\left(\lfloor\frac{y\cdot x_{2}}{y_{2}}\rfloor+1\right)$,可以通过类欧几里得算法计算,时间复杂度为$o(\log n)$

注意到每层只有$o(1)$次上述查询,因此总共只有$o(N)$次查询

总复杂度即$o(N\sqrt{N}\log N+len)$(其中$len=r-l+1$),可以通过

(实际上跑不满,常数极小,甚至于一些比较暴力的代码都可以通过)

 1 #include<bits/stdc++.h>
2 #include<atcoder/math>
3 using namespace std;
4 #define N 300005
5 #define ll long long
6 #define pii pair<int,int>
7 #define fi first
8 #define se second
9 vector<int>ans;
10 int n,aa,bb,vis[N],p[N],mu[N];
11 ll l,r;
12 pii a,b;
13 bool cmp(pii x,pii y){
14 return (ll)x.fi*y.se<(ll)x.se*y.fi;
15 }
16 ll get_g(pii k,int n){
17 return atcoder::floor_sum(n,k.se,k.fi,k.fi+k.se);
18 }
19 ll get_tot(pii k){
20 if (cmp(k,a))k=a;
21 if (cmp(b,k))k=b;
22 ll ans=0;
23 for(int i=1,j;i<=n;i=j+1){
24 j=n/(n/i);
25 ans+=(ll)(mu[j]-mu[i-1])*get_g(k,n/i);
26 }
27 return ans;
28 }
29 void dfs(pii x,pii y){
30 if ((cmp(b,x))||(cmp(y,a)))return;
31 pii m=make_pair(x.fi+y.fi,x.se+y.se);
32 if (m.se>n)return;
33 dfs(x,m);
34 if ((cmp(a,m))&&(cmp(m,b)))ans.push_back(m.se);
35 dfs(m,y);
36 }
37 void calc(pii x,pii y,ll l,ll r,ll s){
38 if ((cmp(b,x))||(cmp(y,a))||(l>s)||(r<1))return;
39 if ((l<=1)&&(s<=r)){
40 dfs(x,y);
41 return;
42 }
43 pii m=make_pair(x.fi+y.fi,x.se+y.se);
44 ll ss=get_tot(m)-get_tot(x);
45 calc(x,m,l,r,ss-1);
46 if ((l<=ss)&&(ss<=r)&&(cmp(a,m))&&(cmp(m,b)))ans.push_back(m.se);
47 calc(m,y,l-ss,r-ss,s-ss);
48 }
49 int main(){
50 mu[1]=1;
51 for(int i=2;i<N;i++){
52 if (!vis[i]){
53 p[++p[0]]=i;
54 mu[i]=-1;
55 }
56 for(int j=1;(j<=p[0])&&(i*p[j]<N);j++){
57 vis[i*p[j]]=1;
58 if (i%p[j])mu[i*p[j]]=mu[i]*mu[p[j]];
59 else{
60 mu[i*p[j]]=0;
61 break;
62 }
63 }
64 }
65 for(int i=1;i<N;i++)mu[i]+=mu[i-1];
66 scanf("%d%d%d%lld%lld",&aa,&bb,&n,&l,&r);
67 int g=__gcd(aa,bb);
68 aa/=g,bb/=g,n/=g;
69 for(int i=0;i<aa;i++)
70 if (((ll)i*bb+1)%aa==0){
71 a=make_pair(i,aa);
72 b=make_pair(((ll)i*bb+1)/aa,bb);
73 break;
74 }
75 if (l>1)l--;
76 else ans.push_back(a.se);
77 r--;
78 pii x=make_pair(0,1),y=make_pair(1,0);
79 calc(x,y,l,r,get_tot(y)-get_tot(x)-1);
80 if (get_tot(y)-get_tot(x)==r)ans.push_back(b.se);
81 for(int i=0;i<ans.size();i++)ans[i]*=g;
82 printf("%d",ans[0]);
83 for(int i=1;i<ans.size();i++)printf(" %d",ans[i]);
84 printf("\n");
85 return 0;
86 }

[atARC123F]Insert Addition的更多相关文章

  1. 省市区三级-sql脚本:

    /*Navicat MySQL Data Transfer Source Server : moiraiSource Server Version : 50631Source Host : 192.1 ...

  2. INSERT ... ON DUPLICATE KEY UPDATE Syntax

    一 mybatis中返回自动生成的id 当有时我们插入一条数据时,由于id很可能是自动生成的,如果我们想要返回这条刚插入的id怎么办呢.在mysql数据中我们可以在insert下添加一个selectK ...

  3. cuda vector addition

    http://webgpu.hwu.crhc.illinois.edu/ // MP 1 #include <wb.h> __global__ void vecAdd(float * in ...

  4. [Swift]LeetCode592. 分数加减运算 | Fraction Addition and Subtraction

    Given a string representing an expression of fraction addition and subtraction, you need to return t ...

  5. INSERT ... ON DUPLICATE KEY UPDATE Syntax 专题

    ON DUPLICATE KEY UPDATE :不用用于批量,除 insert into t1  select * from t2 on duplicated key update k1=v1,k2 ...

  6. CodeFoeces GYM 101466A Gaby And Addition (字典树)

    gym 101466A Gaby And Addition 题目分析 题意: 给出n个数,找任意两个数 “相加”,求这个结果的最大值和最小值,注意此处的加法为不进位加法. 思路: 由于给出的数最多有 ...

  7. 字典树变形 A - Gaby And Addition Gym - 101466A

    A - Gaby And Addition Gym - 101466A 这个题目是一个字典树的变形,还是很难想到的. 因为这题目每一位都是独立的,不会进位,这个和01字典树求最大的异或和是不是很像. ...

  8. 将表里的数据批量生成INSERT语句的存储过程 增强版

    将表里的数据批量生成INSERT语句的存储过程 增强版 有时候,我们需要将某个表里的数据全部或者根据查询条件导出来,迁移到另一个相同结构的库中 目前SQL Server里面是没有相关的工具根据查询条件 ...

  9. SELECT INTO 和 INSERT INTO SELECT 两种表复制语句

    Insert是T-sql中常用语句,Insert INTO table(field1,field2,...) values(value1,value2,...)这种形式的在应用程序开发中必不可少.但我 ...

随机推荐

  1. Asp.Net Core 中的HTTP协议详解

    1.前言 好久没写博客了,最近虽然没什么假期,但是却比以前还忙!工作.工作.工作,就像赶集似的,聚在一起.对于Web开发人员来说,深入了解HTTP有助于我们开发出更好.更高的Web应用程序.当应用程序 ...

  2. 阿里云研究员叔同:Serverless 正当时!

    作者 | 叔同 导读:Serverless 将开发人员从繁重的手动资源管理和性能优化中解放出来,就像数十年前汇编语言演变到高级语言的过程一样,云计算生产力再一次发生变革.Serverless 的核心价 ...

  3. 题解 「BZOJ3636」教义问答手册

    题目传送门 Description 作为泉岭精神的缔造者.信奉者.捍卫者.传承者,Pear决定印制一些教义问答手册,以满足泉岭精神日益增多的信徒.Pear收集了一些有关的诗选.语录,其中部分内容摘录在 ...

  4. 题解 [HAOI2012]道路

    题目传送门 题目大意 给出一个 \(n\) 个点 \(m\) 条边的有向图,问每一条边在多少个最短路径中出现. \(n\le 1500,m\le 5000\) 思路 算我孤陋寡闻了... 很显然,我们 ...

  5. 宙斯盾 DDoS 防护系统“降本增效”的云原生实践

    作者 tomdu,腾讯云高级工程师,主要负责宙斯盾安全防护系统管控中心架构设计和后台开发工作. 导语 宙斯盾 DDoS 防护系统作为公司级网络安全产品,为各类业务提供专业可靠的 DDoS/CC 攻击防 ...

  6. 【数学】快速傅里叶变换(FFT)

    快速傅里叶变换(FFT) FFT 是之前学的,现在过了比较久的时间,终于打算在回顾的时候系统地整理一篇笔记,有写错的部分请指出来啊 qwq. 卷积 卷积.旋积或褶积(英语:Convolution)是通 ...

  7. 在kivy中加图片

    from kivy.app import App from kivy.uix.scatterlayout import ScatterLayout from kivy.uix.image import ...

  8. .Net 5下的单文件部署

    由于.net程序没有静态链接,一直缺乏单文件部署这种干净的发布方案.对客户端程序发布并不是很友好.在之前的.net framework下,有ILMerge合并程序集,以及LibZ的嵌入资源文件等第三方 ...

  9. 基于JWT的Token身份验证

    ​ 身份验证,是指通过一定的手段,完成对用户身份的确认.为了及时的识别发送请求的用户身份,我们调研了常见的几种认证方式,cookie.session和token. 1.Cookie ​ cookie是 ...

  10. 设置nginx进程可打开最大的文件数

    涉及到的nginx配置参数: worker_processes: 表示操作系统启动多少个工作进程在运行,一般这个参数设置成CPU核数的倍数 worker_connections:表示nginx的工作进 ...