根据辗转相减可以知道,相互影响的就是 gcd \gcd相同的那些数。又根据条件 2 2可以知道,所有gcd\gcd相同的数的比例是不会改变的,又因为最开始 a(x,y)=xy a(x,y)=xy是一组解,因此每次操作都相当于把所有 gcd \gcd相同的数修改为 a(x,y)=kxy a(x,y)=kxy。因此,对于修改我们只需要维护 f(d) f(d)表示对于所有 gcd(x,y)=d \gcd(x,y)=d的 (x,y) (x,y)有 a(x,y)=f(d)∗xy a(x,y)=f(d)*xy。
接下来考虑询问,也就是求

====∑i=1n∑j=1nf(gcd(i,j))∗ij∑d=1nf(d)∑i=1n∑j=1nij∗[gcd(i,j)=d]∑d=1nf(d)∗d2∑i=1⌊nd⌋∑j=1⌊nd⌋ij∗e(gcd(i,j))∑d=1nf(d)∗d2∑i=1⌊nd⌋∑j=1⌊nd⌋ij∑x|i,x|jμ(x)∑d=1nf(d)∗d2∑x=1⌊nd⌋μ(x)x2∑i=1⌊ndx⌋∑j=1⌊ndx⌋ij

\begin{align} & \sum_{i=1}^n\sum_{j=1}^nf(\gcd(i,j))*ij \\ = & \sum_{d=1}^nf(d)\sum_{i=1}^n\sum_{j=1}^nij*[\gcd(i,j)=d] \\ = & \sum_{d=1}^nf(d)*d^2\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}ij*e(\gcd(i,j)) \\ = & \sum_{d=1}^nf(d)*d^2\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}ij\sum_{x|i,x|j} \mu(x) \\ = & \sum_{d=1}^nf(d)*d^2\sum_{x=1}^{\lfloor\frac nd\rfloor}\mu(x)x^2\sum_{i=1}^{\lfloor\frac n{dx}\rfloor} \sum_{j=1}^{\lfloor\frac n{dx}\rfloor}ij \end{align}

s(n)=∑i=1ni=n(n+1)2

s(n)=\sum_{i=1}^ni=\frac{n(n+1)}2

g(n)=∑i=1nμ(i)∗i2∗s2(⌊ni⌋)

g(n)=\sum_{i=1}^n\mu(i)*i^2*s^2(\lfloor\frac ni\rfloor)
如果能够预处理出 g g,就可以下底函数分块来求解原问题。但是如果直接依次求是O(nn√)O(n\sqrt n)的,无法接受。考虑递推。注意到 ⌊nd⌋ \lfloor\frac nd\rfloor比 ⌊n−1d⌋ \lfloor\frac{n-1}d\rfloor大 1 1,当且仅当d|nd|n,也就是 n n除以dd余数为零。因此可以得到

g(n)=g(n−1)+∑i|nμ(i)∗i2(s2(ni)−s2(ni−1))=g(n−1)+n3∑i|nμ(i)∗1i

\begin{align} g(n) & =g(n-1)+\sum_{i|n}\mu(i)*i^2(s^2(\frac ni)-s^2(\frac ni-1)) \\ & = g(n-1)+n^3\sum_{i|n}\mu(i)*\frac 1i \end{align}
其中 h(n)=∑i|nμ(i)∗1i h(n)=\sum_{i|n}\mu(i)*\frac 1i为积性函数可以线性筛,于是我们就可以 O(n) O(n)预处理出 g g。
还有一个问题,在对答案进行下底函数分块的时候需要维护f(i)∗i2f(i)*i^2的前缀和,如果直接用树状数组的话,修改是 O(logn) O(\log n)的,询问是 O(n√logn) O(\sqrt n\log n)的,无法接受。因此可以分块,牺牲修改的复杂度来降低询问的复杂度,单次修改 O(n√) O(\sqrt n),单次询问 O(1) O(1)。这样最终的复杂度是 O(n+mn√) O(n+m\sqrt n)。
好像有一点卡常,考虑到比较小的 d=gcd(x,y) d=\gcd(x,y)被调用的次数比较多,可以在分块的时候维护后缀和,这样修改次数可以减少。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define LL long long
const int p=1000000007,maxn=4000010,maxT=2010;
LL f[maxn],g[maxn],h[maxn],inv[maxn],
sum[maxT],sumin[maxT][maxT];
int prm[maxn],have[maxn],bel[maxn],L[maxT],R[maxT],
q,n,T,tot;
int gcd(int x,int y)
{return y?gcd(y,x%y):x;
}
void pause()
{int x;x=1;
}
void init()
{inv[1]=g[1]=h[1]=1;for (int i=2;i<=n;i++){inv[i]=(p-inv[p%i])*(p/i)%p;if (!have[i]){prm[++tot]=i;h[i]=(1-inv[i]+p)%p;}for (int j=1;j<=tot&&(LL)i*prm[j]<=n;j++){have[i*prm[j]]=1;if (i%prm[j]==0){h[i*prm[j]]=h[i];break;}else h[i*prm[j]]=h[i]*h[prm[j]]%p;}g[i]=(g[i-1]+(LL)i*i%p*i%p*h[i])%p;}T=sqrt(n);for (int i=1;i<=T;i++){L[i]=R[i-1]+1;R[i]=i==T?n:L[i]+T-1;for (int j=L[i];j<=R[i];j++){f[j]=1;bel[j]=i;sumin[i][j-L[i]+1]=(sumin[i][j-L[i]]+(LL)j*j)%p;}}for (int i=T;i;i--)sum[i]=(sum[i+1]+sumin[i][R[i]-L[i]+1])%p;
}
LL getsum(int l,int r)
{//if (l==10&&r==13) pause();//LL ret1;int x=bel[l],y=bel[r];if (x==y) return (sumin[x][r-L[x]+1]-sumin[x][l-L[x]]+p)%p;return (sum[x+1]-sum[y]+p+sumin[y][r-L[y]+1]+sumin[x][R[x]-L[x]+1]-sumin[x][l-L[x]]+p)%p;/*LL ret=0;for (int i=l;i<=r;i++) ret=(ret+f[i]*i%p*i%p)%p;if (ret!=ret1) pause();return ret;*/
}
void update(int d)
{for (int j=d;j<=R[bel[d]];j++)sumin[bel[d]][j-L[bel[d]]+1]=(sumin[bel[d]][j-L[bel[d]]]+f[j]*j%p*j)%p;for (int j=bel[d];j;j--)sum[j]=(sum[j+1]+sumin[j][R[j]-L[j]+1])%p;
}
void solve(int m)
{LL ans=0;int u;for (int j=1;j<=m;j=u+1){u=m/(m/j);ans=(ans+getsum(j,u)*g[m/j])%p;}printf("%lld\n",ans);
}
int main()
{/*freopen("table.in","r",stdin);freopen("table.out","w",stdout);*/int xx,yy,m,d;LL x;scanf("%d%d",&q,&n);init();while (q--){scanf("%d%d%lld%d",&xx,&yy,&x,&m);x%=p;d=gcd(xx,yy);f[d]=(LL)x*inv[xx]%p*inv[yy]%p;update(d);solve(m);}
}

【CQOI2017】bzoj4815 小Q的表格相关推荐

  1. 【CQOI2017】小Q的表格

    [CQOI2017]小Q的表格 稍加推导就会发现\(f(a,b)=a\cdot b\cdot h(gcd(a,b))\). 初始时\(h(n)=1\). 询问前\(k\)行\(k\)列时我们就反演: ...

  2. P3700 [CQOI2017]小Q的表格(反演、分块)

    P3700 [CQOI2017]小Q的表格 给定一个大小为n×nn \times nn×n的表格,初始时i,ji, ji,j位置上填的是f(i,j)=i×jf(i, j) = i \times jf( ...

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

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

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

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

  5. [CQOI2017] 小Q的表格(分块 + 整除分块 + 数学 + 前缀和)

    problem luogu-P3700 solution f(a,b)=f(b,a)f(a,b)=f(b,a)f(a,b)=f(b,a) 意味着我们只用考虑半个棋盘的信息. b∗f(a,a+b)=(a ...

  6. P3700-[CQOI2017]小Q的表格【分块,欧拉函数】

    正题 题目链接:https://www.luogu.com.cn/problem/P3700 题目大意 一个n∗nn*nn∗n个数的数字表格,开始位置(a,b)(a,b)(a,b)上的是a∗ba*ba ...

  7. [bzoj4813][Cqoi2017]小Q的棋盘

    来自FallDream的博客,未经允许,请勿转载,谢谢. 小Q正在设计一种棋类游戏.在小Q设计的游戏中,棋子可以放在棋盘上的格点中.某些格点之间有连线,棋子只能在有连线的格点之间移动.整个棋盘上共有V ...

  8. 牛客练习赛81 E. 小 Q 与函数求和 1( “简单莫比乌斯反演” ,欧拉函数性质)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 牛客练习赛81 E. 小 Q 与函数求和 1( "简单莫比乌斯反演" ) Prob ...

  9. 牛客练习赛81 B. 小 Q 与彼岸花(FWT nlogn做法)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Weblink https://ac.nowcoder.com/acm/contest/11171/B ...

最新文章

  1. jquery tooltip
  2. mysql日期时间函数
  3. rocketmq 消息 自定义_RocketMQ的消息发送及消费
  4. pip——【Fatal error in launcher: Unable to create process using 】解决方案
  5. php 数组相乘,PHP如何计算数组中所有值的乘积?(代码示例)
  6. 互联网开源贡献是什么意思_为什么我们为开源软件做出贡献?
  7. [spring源码学习]三、IOC源码——自定义配置文件读取
  8. 基于java SSM的房屋租赁系统设计和实现
  9. 高德公交路径等时线分析
  10. nginx配置错误页面的2种方式
  11. AMOS分析技术:结构方程模型的拟合度评价指标
  12. 张宇考研数学:命题人8套卷使用方法指导,做之前先来看看~
  13. gamit运行时候报错:wrod too long
  14. 实战tkinter图形界面开发_Tkinter python(图形开发界面)
  15. SELECT @@IDENTITY 中的@@是什么意思,如何应用?
  16. python decorate 的秘密
  17. UVALive 6657
  18. Android本地文件存储,机身和外置sd卡
  19. outlook邮箱邮件大小限制_Office Outlook 2010、2013附件大小超过了允许的范围限制三种解决方法图解...
  20. ORB-SLAM2跑TUM RGBD数据集时灰屏卡住

热门文章

  1. 汉语字典数据表 mysql_mysql数据库字典表
  2. canvas html5字符串,具有从右到左字符串的HTML5 Canvas fillText
  3. 蓝桥杯 试题 算法训练 礼物 C++ 详解
  4. 069_ublock
  5. 金山云推HCDN 全面赋能CDN3.0时代
  6. 神经网络输入图片大小,神经网络提取图片特征
  7. Gbase银河麒麟版安装使用
  8. 【Python程序设计】基于Python Flask的网易云音乐歌单采集与可视化分析平台-源码经过调试,100%可运行
  9. 最简单的windows 10 软路由
  10. kali重置登录密码(附镜像)