类欧几里得算法

给出 \(T\) 组询问,每组用 \(n, a, b, c, k_1, k_2\) 来描述。对于每组询问,请你求出

\[\sum_{x = 0} ^ {n} x ^ {k_1} {\left \lfloor \frac{ax + b}{c} \right \rfloor} ^ {k_2}
\]

对 \(1000000007\) 取模。

对于 \(100 \%\) 的数据,\(T = 1000, 1 \le n, a, b, c \le {10} ^ 9, 0 \le k_1 + k_2 \le 10\) 。

数形结合

这里只计算

\[\sum_{i=0}^{N}\lfloor\frac{ai+b}{c}\rfloor
\]

首先通过简单转化把 \(a,b\) 都放到 \(\bmod c\) 的意义下。

考虑计算式 \(\sum_{i=0}^{N}\lfloor\frac{ai+b}{c}\rfloor\) 的含义。它要求的其实是 \(y=\frac{a}{c}x+\frac{b}{c}~(0 \leq x \leq N)\) 这条线段下方(包括线段上)的整点个数。要求整点 \((x\geq 0,y > 0)\)。

使用差分,转化为用 \((0,0) \rightarrow (N,\frac{aN+b}{c})\) 这个矩形里的整点个数减去 \(y=\frac{a}{c}x+\frac{b}{c}~(0 \leq x \leq N)\) 这条线段上方(不包括线段上)的整点个数。要求整点 \((x\geq 0,y > 0)\)。

然后翻转坐标轴, 转化成求 \(y=\frac{c}{a}x-\frac{b}{a}~(0 < x \leq \frac{aN+b}{c})\) 这条线段下方(不包括线段上)的整点个数。要求整点 \((x>0,y\geq 0)\)。

化归原问题,求 \(y=\frac{c}{a}(x+1)-\frac{b}{a}-\frac{1}{a}~(0 \leq x < \frac{aN+b}{c})\) 这条线段下方(包括线段上)的整点个数。要求整点 \((x\geq 0,y \geq 0)\)。\(y=0\) 的那些点要特殊处理掉,由于 \(c-b-1\geq 0\),所以每个可能的横坐标都对应了一个这样的点。

此时相当于求

\[(N+1)\lfloor\frac{aN+b}{c}\rfloor - \sum_{i=0}^{\lfloor\frac{aN+b}{c}\rfloor-1} (\lfloor\frac{ci+c-b-1}{a}\rfloor+1)
\]

此时 \(c>a\),所以可以再次取模,进行递归。注意到在递归中的参数变化:\((a,c)\rightarrow (a\bmod c,c)\rightarrow (c,a\bmod c)\),所以递归层数为 \(O(\log V)\)。

推公式

https://blog.csdn.net/qq_39972971/article/details/94618394

是哪个天才发明的把 \(x^k\) 变成 \(\sum_{i=0}^{x-1}(i+1)^k-i^k\)?

以下考虑实现函数 \(func(N,a,b,c)\) ,计算 \(0\leq k_1+k_2\leq10\) 的情况下所求式子的值,即

\[\sum_{i=0}^{N}i^{k_1}\lfloor\frac{ai+b}{c}\rfloor^{k_2}
\]

递归基

若 \(a=0\) 或 \(\lfloor\frac{aN+b}{c}\rfloor=0\) ,那么, \(\lfloor\frac{ai+b}{c}\rfloor\) 的取值始终相同,答案即为

\[\lfloor\frac{aN+b}{c}\rfloor\sum_{i=0}^{N}i^{k_1}
\]

可以用插值解决。

\(a \geq c\)

若 \(a\geq c\) ,则令 \(q=\lfloor\frac{a}{c}\rfloor,r=a\bmod c\) ,所求式子即为

\[\sum_{i=0}^{N}i^{k_1}(qi+\lfloor\frac{ri+b}{c}\rfloor)^{k_2}\\
=\sum_{i=0}^{N}i^{k_1}\sum_{j=0}^{k_2}\binom{k_2}{j}(qi)^j\lfloor\frac{ri+b}{c}\rfloor^{k_2-j}\\
=\sum_{j=0}^{k_2}\binom{k_2}{j}q^j\sum_{i=0}^{N}i^{k_1+j}\lfloor\frac{ri+b}{c}\rfloor^{k_2-j}
\]

递归计算 \(func(N,r,b,c)\) 即可。

\(b\geq c\)

若 \(b\geq c\) ,则令 \(q=\lfloor\frac{b}{c}\rfloor,r=b\bmod q\),所求式子即为

\[\sum_{i=0}^{N}i^{k_1}(q+\lfloor\frac{ai+r}{c}\rfloor)^{k_2}\\
=\sum_{i=0}^{N}i^{k_1}\sum_{j=0}^{k_2}\binom{k_2}{j}q^j\lfloor\frac{ai+r}{c}\rfloor^{k_2-j}\\
=\sum_{j=0}^{k_2}\binom{k_2}{j}q^j\sum_{i=0}^{N}i^{k_1}\lfloor\frac{ai+r}{c}\rfloor^{k_2-j}
\]

递归计算 \(func(N,a,r,c)\) 即可。

一般情况

否则,即 \(a < c,b < c,\lfloor\frac{aN+b}{c}\rfloor > 0\),令 \(M=\lfloor\frac{aN+b}{c}\rfloor\) 。

注意到 \(\lfloor\frac{ai+b}{c}\rfloor^{k_2}\)​ 较难处理,需要将其变形,有

\[\lfloor\frac{ai+b}{c}\rfloor^{k_2}=\sum_{j=0}^{\lfloor\frac{ai+b}{c}\rfloor-1}((j+1)^{k_2}-j^{k_2})
\]

注意这里规定 \(0^0=0\)。

上述变换的好处是提供了交换求和顺序的可能,由此,原式可变为

\[\sum_{i=0}^{N}i^{k_1}\sum_{j=0}^{\lfloor\frac{ai+b}{c}\rfloor-1}((j+1)^{k_2}-j^{k_2})\\
=\sum_{j=0}^{M-1}((j+1)^{k_2}-j^{k_2})\sum_{i=0}^{N}i^{k_1}[\lfloor\frac{ai+b}{c}\rfloor\geq j+1]\\
=\sum_{j=0}^{M-1}((j+1)^{k_2}-j^{k_2})\sum_{i=0}^{N}i^{k_1}[i>\lfloor\frac{cj+c-b-1}{a}\rfloor]\\
=\sum_{j=0}^{M-1}((j+1)^{k_2}-j^{k_2})\sum_{i=0}^{N}i^{k_1}-\sum_{j=0}^{M-1}((j+1)^{k_2}-j^{k_2})\sum_{i=0}^{\lfloor\frac{cj+c-b-1}{a}\rfloor}i^{k_1}
\]

靠前的求和符号可以直接计算,考虑靠后的求和符号。

\((j+1)^{k_2}-j^{k_2}\)​ 显然是关于 \(j\) 的 \(k_2-1\) 次多项式,而 \(\sum_{i=0}^{\lfloor\frac{cj+c-b-1}{a}\rfloor}i^{k_1}\)​ 也是关于 \(\lfloor\frac{cj+c-b-1}{a}\rfloor\) 的 \(k_1+1\) 次多项式,不妨令为 \(A(x),B(x)\)。

显然 \(A\) 是组合数,\(B\) 可以在一开始就用拉格朗日插值法预处理出来。

那么

\[\sum_{j=0}^{M-1}((j+1)^{k_2}-j^{k_2})\sum_{i=0}^{\lfloor\frac{cj+c-b-1}{a}\rfloor}i^{k_1}\\
=\sum_{i=0}^{M-1}\sum_{j=0}^{k_2-1}A_ji^j\sum_{k=0}^{k_1+1}B_k\lfloor\frac{ci+c-b-1}{a}\rfloor^{k}\\
=\sum_{j=0}^{k_2-1}A_j\sum_{k=0}^{k_1+1}B_k\sum_{i=0}^{M-1}i^j\lfloor\frac{ci+c-b-1}{a}\rfloor^{k}
\]

递归计算 \(func(M-1,c,c-b-1,a)\) 即可。

注意到在递归中的参数变化:\((a,c)\rightarrow (a\bmod c,c)\rightarrow (c,a\bmod c)\),所以递归层数为 \(O(\log V)\)。

时间复杂度 \(O(TK^4\log V)\)。

  1. poly operator*(CO poly&a,CO poly&b){
  2. int n=a.size()-1,m=b.size()-1;
  3. poly ans(n+m+1);
  4. for(int i=0;i<=n;++i)for(int j=0;j<=m;++j)
  5. ans[i+j]=add(ans[i+j],mul(a[i],b[j]));
  6. return ans;
  7. }
  8. poly operator/(poly a,CO poly&b){
  9. int n=a.size()-1,m=b.size()-1;
  10. poly ans(n-m+1);
  11. int inv=fpow(b[m],mod-2);
  12. for(int i=n;i>=m;--i){
  13. ans[i-m]=mul(a[i],inv);
  14. for(int j=i;j>=i-m;--j) a[j]=add(a[j],mod-mul(ans[i-m],b[j-(i-m)]));
  15. }
  16. return ans;
  17. }
  18. poly lagrange(int n,CO poly&x,CO poly&y){
  19. poly ans(n+1),p={1};
  20. for(int i=0;i<=n;++i) p=p*(poly){mod-x[i],1};
  21. for(int i=0;i<=n;++i){
  22. poly q=p/(poly){mod-x[i],1};
  23. int c=1;
  24. for(int j=0;j<=n;++j)if(j!=i) c=mul(c,add(x[i],mod-x[j]));
  25. c=fpow(c,mod-2);
  26. for(int j=0;j<=n;++j) ans[j]=add(ans[j],mul(c,mul(y[i],q[j])));
  27. }
  28. return ans;
  29. }
  30. CO int N=11;
  31. poly sum[N];
  32. int binom[N][N];
  33. struct info {int v[N][N];};
  34. info solve(int64 n,int64 a,int64 b,int64 c){
  35. info ans={};
  36. if(a==0 or (a*n+b)/c==0){
  37. for(int k1=0;k1<=10;++k1){
  38. int s=0;
  39. for(int i=0,t=1;i<=k1+1;++i,t=mul(t,n%mod))
  40. s=add(s,mul(sum[k1][i],t));
  41. int q=(a*n+b)/c%mod;
  42. for(int k2=0,t=1;k1+k2<=10;++k2,t=mul(t,q))
  43. ans.v[k1][k2]=mul(s,t);
  44. }
  45. return ans;
  46. }
  47. if(a>=c){
  48. info tmp=solve(n,a%c,b,c);
  49. for(int k1=0;k1<=10;++k1)for(int k2=0;k1+k2<=10;++k2){
  50. int q=a/c%mod;
  51. for(int i=0,t=1;i<=k2;++i,t=mul(t,q))
  52. ans.v[k1][k2]=add(ans.v[k1][k2],
  53. mul(binom[k2][i],mul(t,tmp.v[k1+i][k2-i])));
  54. }
  55. return ans;
  56. }
  57. if(b>=c){
  58. info tmp=solve(n,a,b%c,c);
  59. for(int k1=0;k1<=10;++k1)for(int k2=0;k1+k2<=10;++k2){
  60. int q=b/c%mod;
  61. for(int i=0,t=1;i<=k2;++i,t=mul(t,q))
  62. ans.v[k1][k2]=add(ans.v[k1][k2],
  63. mul(binom[k2][i],mul(t,tmp.v[k1][k2-i])));
  64. }
  65. return ans;
  66. }
  67. int64 m=(a*n+b)/c;
  68. info tmp=solve(m-1,c,c-b-1,a);
  69. for(int k1=0;k1<=10;++k1){
  70. int s=0;
  71. for(int i=0,t=1;i<=k1+1;++i,t=mul(t,n%mod))
  72. s=add(s,mul(sum[k1][i],t));
  73. for(int k2=0;k1+k2<=10;++k2){
  74. ans.v[k1][k2]=mul(fpow(m%mod,k2),s);
  75. for(int i=0;i<=k2-1;++i)for(int j=0;j<=k1+1;++j)
  76. ans.v[k1][k2]=add(ans.v[k1][k2],mod-
  77. mul(binom[k2][i],mul(sum[k1][j],tmp.v[i][j])));
  78. }
  79. }
  80. return ans;
  81. }
  82. int main(){
  83. for(int i=0;i<=10;++i){
  84. poly x(i+2),y(i+2);
  85. x[0]=0,y[0]=fpow(0,i);
  86. for(int j=1;j<=i+1;++j) x[j]=j,y[j]=add(y[j-1],fpow(j,i));
  87. sum[i]=lagrange(i+1,x,y);
  88. }
  89. for(int i=0;i<=10;++i){
  90. binom[i][0]=binom[i][i]=1;
  91. for(int j=1;j<i;++j) binom[i][j]=add(binom[i-1][j-1],binom[i-1][j]);
  92. }
  93. for(int T=read<int>();T--;){
  94. int64 n=read<int64>(),a=read<int64>(),b=read<int64>(),c=read<int64>();
  95. int k1=read<int>(),k2=read<int>();
  96. printf("%d\n",solve(n,a,b,c).v[k1][k2]);
  97. }
  98. return 0;
  99. }

LOJ138 类欧几里得算法的更多相关文章

  1. [P5170] 类欧几里得算法

    "类欧几里得算法"第二题 P5170 [题意]已知\(n,a,b,c\),求 \[ \begin{aligned} f_{1}(a,b,c,n)&=\sum_{i=0}^n ...

  2. Solution -「LOJ #138」「模板」类欧几里得算法

    \(\mathcal{Description}\)   Link.   \(T\) 组询问,每次给出 \(n,a,b,c,k_1,k_2\),求 \[\sum_{x=0}^nx^{k_1}\left\ ...

  3. Solution -「Luogu 5170」类欧几里得算法

    推柿子大赛了属于是. 题目要求三个柿子,不妨分别记为: \[\begin {align} f (a, b, c, n) &= \sum \limits _{i = 0} ^{n} \lfloo ...

  4. BZOJ3817 Sum(类欧几里得算法)

    设$t=\sqrt r$,原题转化为$\sum_{x=1}^n(4*\lfloor\frac{tx}2\rfloor-2*\lfloor tx\rfloor+1)$考虑如何求$\sum_{x=1}^n ...

  5. Luogu 5170 【模板】类欧几里得算法

    原理不难但是写起来非常复杂的东西. 我觉得讲得非常好懂的博客.   传送门 我们设 $$f(a, b, c, n) = \sum_{i = 0}^{n}\left \lfloor \frac{ai + ...

  6. [BZOJ2987]Earthquake:类欧几里得算法

    分析 类欧的式子到底是谁推的啊怎么这么神仙啊orz! 简单说一下这道题,题目中的约束条件可以转化为: \[ y \leq \frac{c-ax}{b} \] 有负数怎么办啊?转化一下: \[ y \l ...

  7. 洛谷P5170 【模板】类欧几里得算法(数论)

    传送门 此题剧毒,公式恐惧症患者请直接转去代码→_→ 前置芝士 基本数论芝士 题解 本题就是要我们求三个函数的值 \[f(a,b,c,n)=\sum_{i=0}^n \left\lfloor\frac ...

  8. 【LuoguP4433】[COCI2009-2010#1] ALADIN(含类欧几里得算法推导)

    题目链接 题意简述 区间赋值模意义下等差数列,询问区间和 \(N\leq 10^9,Q\leq 10^5\) Sol 每次操作就是把操作区间\([L,R]\)中的数赋值成: \[(X-L+1)*A\ ...

  9. python常用算法(6)——贪心算法,欧几里得算法

    1,贪心算法 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的的时在某种意义上的局部最优解. 贪心算法并不保证会得到最优解,但 ...

随机推荐

  1. JavaSE学习笔记(6)---异常

    JavaSE学习笔记(6)---异常 ​ 软件程序在运行过程中,非常可能遇到问题,我们称之为异常,英文是:Exception,意思是例外.遇到这些例外情况,或者叫异常,我们怎么让写的程序做出合理的处理 ...

  2. thinkphp论坛项目开发

    效果图 首先是数据库 /* Navicat MySQL Data Transfer Source Server : xm Source Server Version : 50553 Source Ho ...

  3. 记一次mysql的问题处理@20181225

    需求:由于某种原因,导致一次分库分表的环境中ddl添加字段和索引没有完全成功,比如100个分库,只有部分修改成功,需要将没有修改成功的库和表找出来,在手动去执行. 由于线上环境,这里模拟还原一下该问题 ...

  4. bugku_web_变量1(CTF)

    这道题考察php全局变量GLOBALS的用法,同样是个php审计题. 看一下代码: flag In the variable ! <?php error_reporting(0); includ ...

  5. CF1299D Around the World

    题意 \(n\)阶无向图,\(m\)条带权边,保证\(1\)不会被"超过\(3\)阶的圈"所包含.求删除与\(1\)相邻的边集,使得不存在从\(1\)出发的权值为\(0\)的非平凡 ...

  6. 剑指offer 14. 链表中倒数第 k 个结点

    14. 链表中倒数第 k 个结点 题目描述 输入一个链表,输出该链表中倒数第k个结点 法一:快慢指针 快指针先走 k 步,等快指针到达尾部时,慢指针所指结点即是倒数第 k 个结点 public cla ...

  7. springboot~gradle4.7之后的lombok引用方法

    在gradle4.7以后对于加入依赖lombok方式发生变化,gradle4.7版本以前,可以直接如下引用: compile("org.projectlombok:lombok:1.18.2 ...

  8. 1、微服务--为什么有consul,consul注册,心跳检测,服务发现

    一.为什么有consul? 在微服务,每1个服务都是集群式的,订单服务在10台服务器上都有,那么用户的请求到达,获取哪台服务器的订单服务呢?如果10台中的有的订单服务挂了怎么办?10台服务器扛不住了, ...

  9. kanbanflow的使用

    也许在工作中大家都听说过番茄工作法,就是每次在一个番茄钟25分钟内保持高度专注,并且在时间结束的时候会提醒你,然后稍作休息5分钟:此外,在产品迭代开发过程中常常会接受到不同的task:那么,我们是否可 ...

  10. 安装SQL Server2008出现Restart computer failed的解决办法

    1.打开注册表编辑器 2.找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager双击文件夹 3.找到PendingF ...