题目描述

小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+7;
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=0;char c=getchar();bool f=0;while(!isdigit(c)){if(c=='-')f=1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}return f?-x:x;
}
inline void work(ll x,ll y){pre[x]=(pre[x]+y)%mod;for(int i=x+1;be[i]==be[i-1];++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]-1])%mod;}
inline void prework(){phi[1]=1;for(int i=2;i<=n;++i){if(!vis[i])prime[++prime[0]]=i,phi[i]=i-1;for(int j=1;j<=prime[0]&&i*prime[j]<=n;++j){vis[i*prime[j]]=1;if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}phi[i*prime[j]]=phi[i]*phi[prime[j]];}}for(int i=1;i<=n;++i)f[i]=(f[i-1]+phi[i]*val[i])%mod;
}
int main(){m=rd();n=rd();n1=sqrt(n);for(int i=1;i<=n;++i){be[i]=(i-1)/n1+1;val[i]=1ll*i*i%mod;(sum[be[i]]+=val[i])%=mod;if(be[i]==be[i-1])pre[i]=(pre[i-1]+val[i])%mod;else pre[i]=val[i];    }for(int i=2;i<=be[n];++i)(sum[i]+=sum[i-1])%=mod;prework();ll a,b,x,k;while(m--){a=rd();b=rd();x=rd();k=rd();ll g=gcd(a,b);ll ans=0,r;x=x/((a/g)*(b/g));x%=mod;work(g,(x-val[g]+mod)%mod);val[g]=x;for(ll l=1;l<=k;l=r+1){r=k/(k/l);ans+=(query(r)-query(l-1))*f[k/l]%mod;ans=(ans%mod+mod)%mod;}printf("%lld\n",ans);}return 0;
}

转载于:https://www.cnblogs.com/ZH-comld/p/10247870.html

[CQOI2017]小Q的表格(数论+分块)相关推荐

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

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

  2. [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 ...

  3. 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( ...

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

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

  5. 【CQOI2017】小Q的表格

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

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

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

  7. 【CQOI2017】bzoj4815 小Q的表格

    根据辗转相减可以知道,相互影响的就是 gcd \gcd相同的那些数.又根据条件 2 2可以知道,所有gcd\gcd相同的数的比例是不会改变的,又因为最开始 a(x,y)=xy a(x,y)=xy是一组 ...

  8. BZOJ 4814 Luogu P3699 [CQOI2017]小Q的草稿 (计算几何、扫描线、set)

    题目链接 (BZOJ) http://lydsy.com/JudgeOnline/problem.php?id=4814 (Luogu) https://www.luogu.org/problem/P ...

  9. bzoj 4813: [Cqoi2017]小Q的棋盘【树形dp】

    这么简单的dp我怎么没想到x2 f为从这个点出发后回到这个点最多能走过的点,g为从这个点出发后不回到这个点最多能走过的点,注意g有两种转移:g[u][k]=max(g[u][k],f[u][k-j-1 ...

最新文章

  1. android 开发 获取各种intent (图片、apk文件、excel、pdf等文件)
  2. elasticsearch原理学习笔记
  3. Docker简介以及mysql和redis的部署
  4. 2022.2.21显示器连接器引脚信号定义1
  5. 吴恩达深度学习笔记7-Course2-Week3【超参数调试、Batch 正则化和程序框架】
  6. 怎么判断linux22端口是否通,在Linux环境下使用SSH判断端口是否通(示例代码)
  7. Linux工作笔记-RabbitMQ的安装
  8. 古风手机壁纸,国潮的你不可错过!
  9. selenium-webdriver自动化测试工具
  10. 读书后对PMP的理解
  11. conda h5py_修改conda安装路径
  12. Boost Asio 使用技巧
  13. 通过python实现txt中,字母概率的计算,以及信源熵的计算,并且输出
  14. HD TUNE以及所有其他硬盘检测工具都不能使用的情况
  15. UE4-手工调整基本姿势
  16. 一种分数微分基方法用于多尺度纹理增强(Fractional Differential Mask: A Fractional Differential-Based Approach for Multi)
  17. 复数值神经网络matlab,学界 | Yoshua Bengio等提出深度复数网络:用复数构建深度神经网络(已开源)...
  18. 影视后期制作学习(AE)(父子级链接-表达式)
  19. WinRAR 压缩文件的时候排除指定的目录文件夹
  20. win7/win10下KiWi Syslog服务器的安装与配置

热门文章

  1. C++中有了malloc/free 为什么还要new/delete?
  2. tar 打包、压缩和备份
  3. requests库学习
  4. 21天Jmeter打卡Day18 前置处理器_熟悉常用组件
  5. 软件测试从业者,Linux知识从入门到玩转(必读)
  6. linux xampp图形界面,linux下安装xampp,XAMPP目录结构
  7. MySQL数值型超出范围_MySQL 数值类型溢出处理
  8. 免校准的电量计量芯片_交直流两用计量芯片HLW8112
  9. 欧洲英语语言c1证书,威尼斯大学认可的英语语言证书
  10. 动态展开所有_动态演示立方体的展开,并且显示11种展开图——GeoGebra制作教程...