[CQOI2017]小Q的表格(数论+分块)
题目描述
小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之后的结果。
题解
这题思路太神了。
乍一看需要维护一个二维的东西看起来很麻烦,但实际上是可以转化为一维上的问题的。
先来看第一个限制,关于对角线对称的数字相等,这样我们的棋盘大小变为原来的一半。
然后看第二个限制,挪一下位置,变成了
f(a,a+b)/(a+b)=f(a,b)/b
f(a,a+b)/((a+b)*a)=f(a,b)/(a*b)
我们发现了规律,f(a,b)是和a*b正相关的,而且这种关系非常像辗转相减,那么一直减到最后就会变成f(gcd,gcd)。
于是我们得出了结论,每个位置(a,b)的值之和gcd(a,b)相关。
于是它变成了一个序列上的问题,每次修改只需要修改一个数。
然后考虑答案。
ans=∑f(g,g)∑∑i*j*(gcd(i,j)==g) i,j,g<=k
后面的那个东西∑∑i*j*(gcd(i,j)==g)经过推导后可以得到∑i*i*Φ(i) i<=k/g
然后就可以除法分块了。
但我们还需要支持单点修改,区间求和,可以用树状数组,但是这题的数据范围比较特别,所以用分块搞就可以了,根号修改,O(1)查询。
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#define N 4000009
using namespace std;
typedef long long ll;
const int mod=1e9+;
ll n,m,sum[N],pre[N],phi[N],prime[N],f[N],val[N],n1,be[N];
bool vis[N];
inline ll rd(){
ll x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
inline void work(ll x,ll y){
pre[x]=(pre[x]+y)%mod;
for(int i=x+;be[i]==be[i-];++i)pre[i]=(pre[i]+y)%mod;
for(int i=be[x];i<=be[n];++i)sum[i]=(sum[i]+y)%mod;
}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll query(int x){return (pre[x]+sum[be[x]-])%mod;}
inline void prework(){
phi[]=;
for(int i=;i<=n;++i){
if(!vis[i])prime[++prime[]]=i,phi[i]=i-;
for(int j=;j<=prime[]&&i*prime[j]<=n;++j){
vis[i*prime[j]]=;
if(i%prime[j]==){phi[i*prime[j]]=phi[i]*prime[j];break;}
phi[i*prime[j]]=phi[i]*phi[prime[j]];
}
}
for(int i=;i<=n;++i)f[i]=(f[i-]+phi[i]*val[i])%mod;
}
int main(){
m=rd();n=rd();n1=sqrt(n);
for(int i=;i<=n;++i){
be[i]=(i-)/n1+;val[i]=1ll*i*i%mod;
(sum[be[i]]+=val[i])%=mod;
if(be[i]==be[i-])pre[i]=(pre[i-]+val[i])%mod;
else pre[i]=val[i];
}
for(int i=;i<=be[n];++i)(sum[i]+=sum[i-])%=mod;
prework();ll a,b,x,k;
while(m--){
a=rd();b=rd();x=rd();k=rd();ll g=gcd(a,b);ll ans=,r;
x=x/((a/g)*(b/g));x%=mod;work(g,(x-val[g]+mod)%mod);val[g]=x;
for(ll l=;l<=k;l=r+){
r=k/(k/l);
ans+=(query(r)-query(l-))*f[k/l]%mod;
ans=(ans%mod+mod)%mod;
}
printf("%lld\n",ans);
}
return ;
}
[CQOI2017]小Q的表格(数论+分块)的更多相关文章
- [BZOJ4815][CQOI2017]小Q的表格 数论+分块
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4815 题目中所给条件中的$(a,a+b)$和$(a,b)$的关系很瞩目. 然后大家都知道$ ...
- bzoj 4815: [Cqoi2017]小Q的表格 [数论]
4815: [Cqoi2017]小Q的表格 题意: 单点修改,查询前缀正方形和.修改后要求满足条件f(a,b)=f(b,a), b×f(a,a+b)=(a+b)*f(a,b) 一开始sb了认为一次只会 ...
- bzoj 4815 [Cqoi2017]小Q的表格——反演+分块
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4815 大概就是推式子的时候注意有两个边界都是 n ,考虑变成 2*... 之类的. 分块维护 ...
- 【BZOJ4815】[CQOI2017]小Q的表格(莫比乌斯反演,分块)
[BZOJ4815][CQOI2017]小Q的表格(莫比乌斯反演,分块) 题面 BZOJ 洛谷 题解 神仙题啊. 首先\(f(a,b)=f(b,a)\)告诉我们矩阵只要算一半就好了. 接下来是\(b* ...
- 洛咕 P3700 [CQOI2017]小Q的表格
洛咕 P3700 [CQOI2017]小Q的表格 神仙题orz 首先推一下给的两个式子中的第二个 \(b\cdot F(a,a+b)=(a+b)\cdot F(a,b)\) 先简单的想,\(F(a,a ...
- [BZOJ4815][CQOI2017]小Q的表格(莫比乌斯反演)
4815: [Cqoi2017]小Q的表格 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 832 Solved: 342[Submit][Statu ...
- bzoj 4815: [Cqoi2017]小Q的表格【欧拉函数+分块】
参考:http://blog.csdn.net/qq_33229466/article/details/70174227 看这个等式的形式就像高精gcd嘛-所以随便算一下就发现每次修改(a,b)影响到 ...
- [bzoj4815]: [Cqoi2017]小Q的表格
来自FallDream的博客,未经允许,请勿转载,谢谢. 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理.每当小Q不知道如何解决时,就只好向你求助. ...
- [bzoj4815] [洛谷P3700] [Cqoi2017] 小Q的表格
Description 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理. 每当小Q不知道如何解决时,就只好向你求助.为了完成任务,小Q需要列一个表格 ...
随机推荐
- UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-25: ordinal not in range(128)
python报错:UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-25: ordinal not in ...
- 网站之.htaccess文件
Apache系统中的.htaccess文件(分布式配置文件)提供了针对目录改变配置的方法,也就是在一个特定的文件目录中放置一个包含指令的文件,以作用于此目录以及所有子目录.直白的说,.htaccess ...
- Redis教程(Windows)
安装 1)下载redis压缩包并 , 推荐地址:https://github.com/MSOpenTech/redis/releases Redis 支持 32 位和 64 位.这个需要根据你系统平 ...
- python文件封装成*.exe文件(单文件和多文件)
环境:win10 64位 python3.7 单*.py文件打包Python GUI:程序打包为exe 一.安装Pyinstaller,命令pip install Pyinstaller,(大写的P ...
- 解决多人开发时使用window.onload的覆盖问题
通用型小函数:解决多人开发时,同时使用window.onload事件所出现的后面的window.onload函数覆盖前面一个window.onload函数的问题. function addLoadEv ...
- NOIP2015提高组复赛B 子串
题目链接:https://ac.nowcoder.com/acm/contest/263/B 题目大意: 略 分析: 设preA(i)为字符串A中第1个字符到第i个字符构成的字符串. 设preB(i) ...
- 记一次ntp反射放大ddos攻击
2018/3/26 ,共计310G左右的DDoS攻击 临时解决办法:将web服务转移到同生产一个内网段的备份服务器a上,a提供web端口80,数据库通过内网连接还是沿用生产数据库. 后续解决办法:通过 ...
- PHPStorm从入门到精通
1. 使用phpstorm+xdebug进行调试 首先,安装php的xdebug扩展 查看phpinfo中php的版本,php的安装位数,php的是否线程安全:根据这些下载对应的xdebug.dll ...
- font_awesome的icon库的使用
1.使用cdn引入font_awesome图标库的css文件 例如:index.htm <html><head><title>font_awesome test&l ...
- adoquery.refresh和adoquery.query的区别
大的区别没有 1: requery是通过重新发出原始命令并再次检索数据,可使用 Requery 方法刷新来自数据源的 Recordset 对象的全部内容.调用该方法等于相继调用 Close 和 Ope ...