来自FallDream的博客,未经允许,请勿转载,谢谢。


小Q是个程序员。
作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理。每当小Q不知道如何解决时,就只好向你求助。为了完成任务,小Q需要列一个表格,表格有无穷多行,无穷多列,行和列都从1开始标号。为了完成任务,表格里面每个格子都填了一个整数,为了方便描述,小Q把第a行第b列的整数记为f(a,b),为了完成任务,这个表格要满足一些条件:(1)对任意的正整数a,b,都要满足f(a,b)=f(b,a);(2)对任意的正整数a,b,都要满足b×f(a,a+b)=(a+b)*f(a,b)。为了完成任务,一开始表格里面的数很有规律第a行第b列的数恰好等于a*b,显然一开始是满足上述两个条件的。为了完成任务,小Q需要不断的修改表格里面的数,每当修改了一个格子的数之后,为了让表格继续满足上述两个条件,小Q还需要把这次修改能够波及到的全部格子里都改为恰当的数。由于某种神奇的力量驱使,已经确保了每一轮修改之后所有格子里的数仍然都是整数。为了完成任务,小Q还需要随时获取前k行前k列这个有限区域内所有数的和是多少,答案可能比较大,只需要算出答案mod1,000,000,007之后的结果。
每次修改操作把(a,b)改成x并且求前k行k列的和
操作数量m<=10000  n,k,a,b<=4*10^6  x<=10^18
 
首先从条件入手,发现很像辗转相除法。仔细观察发现,f(a,b)总是和f(g,g)( g=gcd(a,b) )有关系。更详细地,g(a,b)=f(g,g)*a/g*b/g
所以只需要几下主对角线的数字即可,考虑计算答案。以下的n表示询问的k,且num(x)表示f(x,x)
枚举gcd是啥
$$Ans=\sum_{g=1}^{n}num(g)*\sum_{i=1}^{\lfloor\frac{n}{g}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{g}\rfloor}ijg^{2}*[gcd(i,j)==1]$$
当然,把后面那一坨提出来比较舒服,发现可以用phi来化简
$$G(n)=\sum_{i=1}^{n}\sum_{j=1}^{n}i*j*[gcd(i,j)==1]$$
因为$$\sum_{i=1}^{n}i*[gcd(i,n)==1]=\frac{n*\varphi(n)}{2}$$
所以$$G(n)=\sum_{i=1}^{n}i^{2}\varphi(i)$$
显然可以打表
然后这时候
$$Ans=\sum_{g=1}^{n}num(g)*G(\lfloor\frac{n}{g}\rfloor)$$
$\lfloor\frac{n}{g}\rfloor$只有根号种取值,所以只需要维护前面那东西的前缀和就行了
但是每次查询必须是O(1)的,很自然想到分块维护前缀和,修改的时候直接修改gcd即可。这样就做完啦。
复杂度是$O(m\sqrt{n})$
 
强行写了一个llread返回个int查了好久错...心塞
#include<iostream>
#include<cstdio>
#include<cmath>
#define ll long long
#define MN 4000000
#define MB 2000
#define mod 1000000007
using namespace std;
inline int read()
{
int x = ; char ch = getchar();
while(ch < '' || ch > '')ch = getchar();
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x;
}
inline ll llread()
{
ll x = ; char ch = getchar();
while(ch < '' || ch > '') ch = getchar();
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x;
}
int n,m,phi[MN+],s[MN],cnt=,la,block,add[MB+];
int num[MN+];
bool b[MN+]; inline int gcd(int x,int y) {return !y?x:gcd(y,x%y);} void Modify(int x,int ad)
{
int bl=(x-)/block+,M=min(n,bl*block);
for(int j=bl+;j<=la;++j) (add[j]+=ad)%=mod;
for(int j=x;j<=M;++j) (num[j]+=ad)%=mod;
} int Query(int x)
{
if(!x) return ;
int bl=(x-)/block+;
return (num[x]+add[bl])%mod;
} int main()
{
m=read();n=read();num[]=phi[]=;block=sqrt(n);la=(n-)/block+;
for(int i=;i<=n;++i)
{
if(!b[i]) phi[s[++cnt]=i]=i-;
for(int j=;s[j]*i<=n;++j)
{
b[s[j]*i]=;
if(i%s[j]==){ phi[s[j]*i]=phi[i]*s[j];break;}
phi[s[j]*i]=phi[i]*(s[j]-);
}
phi[i]=(phi[i-]+1LL*i*i%mod*phi[i])%mod;
num[i]=(num[i-]+1LL*i*i)%mod;
}
for(int i=;i<=m;++i)
{
int x=read(),y=read();ll X=llread();int k=read();
int g=gcd(x,y),ans=;X/=1LL*(x/g)*(y/g);X%=mod;
Modify(g,((X-Query(g)+mod)%mod+Query(g-))%mod);
for(int j=,last;j<=k;j=last+)
{
last=k/(k/j);
ans=(ans+1LL*(Query(last)-Query(j-)+mod)%mod*phi[k/j])%mod;
}
printf("%d\n",ans);
}
return ;
}

[bzoj4815]: [Cqoi2017]小Q的表格的更多相关文章

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

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

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

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

  3. [BZOJ4815][CQOI2017]小Q的表格 数论+分块

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4815 题目中所给条件中的$(a,a+b)$和$(a,b)$的关系很瞩目. 然后大家都知道$ ...

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

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

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

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

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

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

  7. [bzoj4815] [洛谷P3700] [Cqoi2017] 小Q的表格

    Description 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理. 每当小Q不知道如何解决时,就只好向你求助.为了完成任务,小Q需要列一个表格 ...

  8. [CQOI2017]小Q的表格(数论+分块)

    题目描述 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理.每当小Q不知道如何解决时,就只好向你求助. 为了完成任务,小Q需要列一个表格,表格有无穷多 ...

  9. bzoj4815[CQOI2017]小Q的格子

    题意 不简述题意了,简述题意之后这道题就做出来了.放个原题面. 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理. 每当小Q不知道如何解决时,就只好向 ...

随机推荐

  1. javascript抛物投栏(抛物线实践)

    平面内,到定点与定直线的距离相等的点的轨迹叫做抛物线.水平抛物线就是水平匀速,垂直加速的运动. 抛物线的性质:面内与一个定点F和一条定直线l 的距离相等的点的轨迹叫做抛物线. 定点F叫做抛物线的焦点. ...

  2. signalR 消息推送

    业务情景一:上传报表,上传excel.如果excel的数据量很大,上万条,上十万条数据,那么这个上传请求必然是个耗时请求.用户上传之后,很关心上传的进度和结果. 业务情景二:站内消息提醒,实时有效地接 ...

  3. 构建微服务开发环境8————Hello 微服务

    [内容指引] 1.用IDEA打开微服务项目; 2.更新Maven依赖: 3.IntelliJ IDEA JDK配置; 4.修改代码: 5.运行微服务: 6.将代码变更提交到Github. 经过前面的努 ...

  4. Microsoft dynamic 批量更新

    //批量处理 ExecuteMultipleRequest multipleRequest = new ExecuteMultipleRequest() { Settings = new Execut ...

  5. Zepto.js库touch模块代码解析

    Zepto.js也许并不陌生,专门针对移动端开发,Zepto有一些基本的触摸事件可以用来做触摸屏交互(tap事件.swipe事件),Zepto是不支持IE浏览器的. 下面来解析一些Zepto.js触摸 ...

  6. kubernetes进阶(05)kubernetes的命令

    在Kubernetes中,Node.Pod.Replication Controller.Service等概念都可以看作一种资源对象,通过Kubernetes提供的Kubectl工具或者API调用进行 ...

  7. 阿里云API网关(16)客户端请求的https支持

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  8. C#微信公众号开发——access_token的获取

    access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_toke ...

  9. 详解Ajax请求(二)——异步请求原理的分析

    在上一文章里,我们分析了同步请求的原理.当浏览器向服务器发送同步请求时,服务处理同步请求的过程中,浏览器会处于等待的状态,服务器处理完请求把数据响应给浏览器并覆盖浏览器内存中原有的数据,浏览器重新加载 ...

  10. JS中apply和call的应用和区别

    因为object没有某个方法,但是别的对象有,可以借助apply或call像别的对象借方法来操作. 猫吃鱼,狗吃肉,奥特曼打小怪兽. 有天狗想吃鱼了 猫.吃鱼.call(狗,鱼) 狗就吃到鱼了 猫成精 ...