(Updated 2018.04.28 : 发现公式效果不好,重新处理图片)
国际惯例的题面:

看到这两个公式,很多人都会想到与gcd有关。没错,最终的结论就是f(a,b)=f(gcd(a,b))*(a/gcd(a,b))*(b/gcd(a,b))。然而结论只能猜出来是不行的,我们考虑如何证明他。
网上很多大神的构造性证明已经很清楚了,然而我太菜,不会构造,让我们来一发非构造性证明。

由于:


我们设x=a+b,则b=x-a,显然我们有前提条件x≠a。
用x替换b,得:


我们移项,得:


如果x≥2*a,我们可以继续迭代:


如果我们让上面两个等式相乘,会发现:


显然迭代下去,我们会有:


如果x=p*a,我们令k=p-1,我们有:


如果我们令k=(x/a)(下取整),我们有:


然而我们现在连右边那个东西能否整除都不知道……没关系,继续展开等式。


我们看到了一个非常愉悦的事情:两个x%a约掉了。
仔细观察,会发现分子上的东西是f的第二个参数的连乘积,分母上的东西是f的第二个参数取模第一个参数的连乘积(废话)。
考虑我们一直迭代下去,最终会剩下什么。
迭代终止的条件是x%a=0,这时候我们带入前面推出x=p*a时适用的公式,的那个这样会剩下分子的前两项和分母的最后两项。
显然分子剩下的前两项为x和a,分母剩下的最后一项为gcd(a,b),而根据上面迭代的等式,分母的倒数第二项为倒数第二次带入f()的第一个参数,显然也是gcd(a,b)。
至此我们的结论得证(一个证明搞这么麻烦,我好蒻啊)。

然后就是计算的问题。
我们要求的是:

如果我们能够预处理出g(),O(sqrt(n))修改并O(1)查询f()的前缀和,我们就能在sqrt(n)的复杂度内完成每次操作。
显然维护f()直接大力块状数组即可,重点是g()。

这里有一个很优美的结论,就是


然后我们就有:

之后线性筛φ就好了。

代码(老年选手已经毫不畏惧卡常数):

 #include<cstdio>
#include<algorithm>
#include<cmath>
#define bool unsigned char
#define debug cout
typedef long long int lli;
const int maxn=4e6+1e2,maxb=2e3+1e2;
const int mod=1e9+; lli phi[maxn];
int n,m; inline lli fastpow(lli base,int tim) {
lli ret = ; base %= mod;
while(tim) {
if( tim & ) ret = ret * base % mod;
if( tim >>= ) base = base * base % mod;
}
return ret;
}
inline int gcd(int x,int y) {
register int t;
while( ( t = x % y ) ) x = y , y = t;
return y;
} namespace Pre {
inline void sieve() {
static int prime[maxn],cnt;
static bool vis[maxn];
phi[] = ;
for(int i=;i<=n;i++) {
if( !vis[i] ) prime[++cnt] = i , phi[i] = i - ;
for(int j=;j<=cnt&&(lli)i*prime[j]<=n;j++) {
const int tar = i * prime[j];
vis[tar] = ;
if( i % prime[j] ) phi[tar] = phi[i] * ( prime[j] - );
else {
phi[tar] = phi[i] * prime[j];
break;
}
}
}
for(int i=;i<=n;i++) phi[i] = ( phi[i] * i % mod * i % mod + phi[i-] ) % mod;
}
} struct BlockedArrary {
lli dat[maxn],sumins[maxn],blk[maxb],sumblk[maxb];
int bel[maxn],st[maxb],ed[maxb],blksiz,cnt; inline lli query(int pos) {
return pos ? ( sumblk[bel[pos]-] + sumins[pos] ) % mod : ;
}
inline void update(int pos,lli val) {
dat[pos] = val;
int id = bel[pos] , l = st[id] , r = ed[id];
sumins[l] = dat[l]; for(int i=std::max(pos,l+);i<=r;i++) sumins[i] = ( sumins[i-] + dat[i] ) % mod;
blk[id] = sumins[r]; for(int i=id;i<=cnt;i++) sumblk[i] = ( sumblk[i-] + blk[i] ) % mod;
}
inline void init() {
for(int i=;i<=n;i++) dat[i] = (lli) i * i % mod;
blksiz = std::sqrt(n);
for(int l=,r;l<=n;l=r+) {
r = std::min( l + blksiz - , n ) , ++cnt , st[cnt] = l , ed[cnt] = r , sumins[l] = dat[l];
for(int i=l;i<=r;i++) bel[i] = cnt;
for(int i=l+;i<=r;i++) sumins[i] = ( sumins[i-] + dat[i] ) % mod;
sumblk[cnt] = ( sumblk[cnt-] + ( blk[cnt] = sumins[r] ) ) % mod;
}
}
}ba; inline void update(int a,int b,lli d) {
int g = gcd(a,b);
lli tv = d % mod * fastpow((lli)a*b/g/g,mod-) % mod;
ba.update(g,tv);
} inline lli query(int k) {
lli ret = ;
for(int i=,j;i<=k;i=j+) {
j = k / ( k / i );
ret = ( ret + ( ba.query(j) - ba.query(i-) + mod ) % mod * phi[k/i] % mod ) % mod;
}
return ret;
} int main() {
static int a,b,k;
static lli x;
scanf("%d%d",&m,&n) , Pre::sieve() , ba.init();
while(m--) scanf("%d%d%lld%d",&a,&b,&x,&k) , update(a,b,x) , printf("%lld\n",query(k));
return ;
}

過去の想い 記憶の彼方
过往的思念 记忆中的远方
幼き日 残した悔い
稚气时光中 所留下的懊悔
胸の奥 刻む針音(しんおん)
内心深处 铭刻下心音
心だけ 置き忘れたまま
让它留在心里慢慢被遗忘吧

4815: [Cqoi2017]小Q的表格 莫比乌斯反演 分块的更多相关文章

  1. [BZOJ4815][CQOI2017]小Q的表格(莫比乌斯反演)

    4815: [Cqoi2017]小Q的表格 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 832  Solved: 342[Submit][Statu ...

  2. bzoj 4815: [Cqoi2017]小Q的表格 [数论]

    4815: [Cqoi2017]小Q的表格 题意: 单点修改,查询前缀正方形和.修改后要求满足条件f(a,b)=f(b,a), b×f(a,a+b)=(a+b)*f(a,b) 一开始sb了认为一次只会 ...

  3. BZOJ 4815 CQOI2017 小Q的表格 欧拉函数+分块

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4815 题意概述:要认真概述的话这个题就出来了... 分析: 首先分析题目,认真研究一下修 ...

  4. bzoj 4815 [Cqoi2017]小Q的表格——反演+分块

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4815 大概就是推式子的时候注意有两个边界都是 n ,考虑变成 2*... 之类的. 分块维护 ...

  5. bzoj 4815: [Cqoi2017]小Q的表格【欧拉函数+分块】

    参考:http://blog.csdn.net/qq_33229466/article/details/70174227 看这个等式的形式就像高精gcd嘛-所以随便算一下就发现每次修改(a,b)影响到 ...

  6. BZOJ 4815 [Cqoi2017]小Q的表格 ——欧拉函数

    把式子化简一波. 发现一个比较厉害的性质:每个点只能影响到行列下标$gcd$与它相同的点. 然后就可以计算$\sum_{g<=k}f(g,g)*\sum_{i<=k}\sum_{j< ...

  7. BZOJ4815 [CQOI2017]小Q的表格 【数论 + 分块】

    题目链接 BZOJ4815 题解 根据题中的式子,手玩一下发现和\(gcd\)很像 化一下式子: \[ \begin{aligned} bf(a,a + b) &= (a + b)f(a,b) ...

  8. 【BZOJ4815】[CQOI2017]小Q的表格(莫比乌斯反演,分块)

    [BZOJ4815][CQOI2017]小Q的表格(莫比乌斯反演,分块) 题面 BZOJ 洛谷 题解 神仙题啊. 首先\(f(a,b)=f(b,a)\)告诉我们矩阵只要算一半就好了. 接下来是\(b* ...

  9. 洛咕 P3700 [CQOI2017]小Q的表格

    洛咕 P3700 [CQOI2017]小Q的表格 神仙题orz 首先推一下给的两个式子中的第二个 \(b\cdot F(a,a+b)=(a+b)\cdot F(a,b)\) 先简单的想,\(F(a,a ...

随机推荐

  1. <crtdbg.h> 的作用

    1.在调试状态下让win程在输出窗口中显示调试信息,可以用_RPTn 宏n为显示参数比如_RPT0(_CRT_WARN,"text"); _RPT1(_CRT_WARN," ...

  2. ARMV8 datasheet学习笔记4:AArch64系统级体系结构之Generic timer

    1.前言 2.generate timer 2.1 概述 提供了一个系统计数器,用来实时测量流逝的时间: 提供了一个虚拟计数器,用来测量某个虚拟机上流逝的虚拟时间: 定时器,每隔一段时间会触发事件,支 ...

  3. 调用链系列一、Zipkin架构介绍、Springboot集承(springmvc,HttpClient)调用链跟踪、Zipkin UI详解

    1.Zipkin是什么 Zipkin分布式跟踪系统:它可以帮助收集时间数据,解决在microservice架构下的延迟问题:它管理这些数据的收集和查找:Zipkin的设计是基于谷歌的Google Da ...

  4. 如何在windows上调试安卓机谷歌浏览器上的页面

    - 下面的方法仅在windows和安卓机上测试过,,,, - 手机(安卓机)需要安装chrome与电脑(Windows)上的chrome配合,也就是只能调试谷歌浏览器上的页面 1.手机的准备工作 打开 ...

  5. 018_nginx_proxy死循环问题

    今天线上遇到一个请求一次,触发多次的请求,而且直接把nginx机器压垮了.经排查,经过如下: 一. server{ server www.jyall.com; location /latestrele ...

  6. Bootstrap报错:Bootstrap's JavaScript requires jQuery

    如题,经百度原来导入顺序的问题,须要先导入Jqeury库,今记之!

  7. 每天一个linux命令:scp命令

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  8. C#面向对象(封装)

    以上就是面向对象的封装和初始化:

  9. Oracle 11g安装步骤以及Oracle11g创建表空间和用户,并授权

    Oracle 11g安装步骤详解 一.Oracle 下载 注意Oracle分成两个文件,下载完后,将两个文件解压到同一目录下即可. 路径名称中,最好不要出现中文,也不要出现空格等不规则字符. 官方下地 ...

  10. VIM 键盘符号

    :h key-notation //查询键盘符号说明<>> 等于shift + > % 是跳到对应的括号 x 是删除当前字符,即右括号 '' 是跳回左括号 x 删除左括号