来自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. 201421123042 《Java程序设计》第12周

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 面向系统综合设计-图书馆管理系统或购物车 使用流与文件改造你的图书馆管理系统或购物车. 2.1 简述如何 ...

  2. 《javascript设计模式与开发实践》阅读笔记(15)—— 装饰者模式

    装饰者模式 可以动态地给某个对象添加一些额外的职责,而不会影响从这个类中派生的其他对象.在程序开发中,许多时候都并不希望某个类天生就非常庞大,一次性包含许多职责.那么我们就可以使用装饰者模式. 代码例 ...

  3. Mysql数据库主从配置

    一.为什么要使用数据库主从架构 一个网站损耗资源最厉害的就是数据库,最易崩溃的也是数据库,而数据库崩溃带来的后果是非常严重的.数据库分为读和写操作,在实际的应用中,读操作的损耗远比写操作多太多,因此读 ...

  4. 解决IE8下CSS3选择器 :nth-child() 不兼容的问题

    1.定义和用法 :nth-child(n) 选择器匹配属于其父元素的第 N 个子元素,不论元素的类型. n 可以是数字.关键词或公式. <ul> <li>1</li> ...

  5. 回收 PV - 每天5分钟玩转 Docker 容器技术(152)

    当 PV 不再需要时,可通过删除 PVC 回收. 当 PVC mypvc1 被删除后,我们发现 Kubernetes 启动了一个新 Pod recycler-for-mypv1,这个 Pod 的作用就 ...

  6. 多线程里面的关键字,wait, notfiy, 锁(synchronized), lock接口

    多线程环境下,必须考虑线程同步的问题,这是因为多个线程同时访问变量或者资源时会有线程争用,比如A线程读取了一个变量,B线程也读取了这个变量,然后他们同时对这个变量做了修改,写回到内存中,由于是同时做修 ...

  7. linux下mongodb安装、服务器、客户端、备份、账户命令

    在linux环境安装mongoDB: 一般认为偶数版本为稳定版 如 1.6.x,奇数版本为开发版如1.7.x 32bit的mongoDB最大能存放2g的数据,64bit没有限制 方法1: 终端执行: ...

  8. 【第十九篇】laydate设置起始时间,laydate设置开始时间和结束时间

    laydate设置开始时间后,结束时间不可小于已选择的开始时间 laydate设置结束时间后,开始时间不可小于已选择的结束时间 //设置开始时间 var startDate = laydate.ren ...

  9. 【WebGL入门】画一个旋转的cube

    最近搜罗了各种资料,发现WebGL中文网特别好用,很适合新手入门:http://www.hewebgl.com/article/getarticle/50 只需要下载好需要的所有包,然后用notepa ...

  10. ZOJ-2913 Bus Pass---BFS进阶版

    题目链接: https://vjudge.net/problem/ZOJ-2913 题目大意: 问哪个区域到公交路线上所有区域的最大距离最小 思路: 这里要求出到底是哪个区域到某些指定区域的最大距离最 ...