[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+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的表格(数论+分块)相关推荐
- [BZOJ4815][CQOI2017]小Q的表格 数论+分块
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4815 题目中所给条件中的$(a,a+b)$和$(a,b)$的关系很瞩目. 然后大家都知道$ ...
- [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 ...
- 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( ...
- P3700-[CQOI2017]小Q的表格【分块,欧拉函数】
正题 题目链接:https://www.luogu.com.cn/problem/P3700 题目大意 一个n∗nn*nn∗n个数的数字表格,开始位置(a,b)(a,b)(a,b)上的是a∗ba*ba ...
- 【CQOI2017】小Q的表格
[CQOI2017]小Q的表格 稍加推导就会发现\(f(a,b)=a\cdot b\cdot h(gcd(a,b))\). 初始时\(h(n)=1\). 询问前\(k\)行\(k\)列时我们就反演: ...
- [bzoj4813][Cqoi2017]小Q的棋盘
来自FallDream的博客,未经允许,请勿转载,谢谢. 小Q正在设计一种棋类游戏.在小Q设计的游戏中,棋子可以放在棋盘上的格点中.某些格点之间有连线,棋子只能在有连线的格点之间移动.整个棋盘上共有V ...
- 【CQOI2017】bzoj4815 小Q的表格
根据辗转相减可以知道,相互影响的就是 gcd \gcd相同的那些数.又根据条件 2 2可以知道,所有gcd\gcd相同的数的比例是不会改变的,又因为最开始 a(x,y)=xy a(x,y)=xy是一组 ...
- BZOJ 4814 Luogu P3699 [CQOI2017]小Q的草稿 (计算几何、扫描线、set)
题目链接 (BZOJ) http://lydsy.com/JudgeOnline/problem.php?id=4814 (Luogu) https://www.luogu.org/problem/P ...
- bzoj 4813: [Cqoi2017]小Q的棋盘【树形dp】
这么简单的dp我怎么没想到x2 f为从这个点出发后回到这个点最多能走过的点,g为从这个点出发后不回到这个点最多能走过的点,注意g有两种转移:g[u][k]=max(g[u][k],f[u][k-j-1 ...
最新文章
- android 开发 获取各种intent (图片、apk文件、excel、pdf等文件)
- elasticsearch原理学习笔记
- Docker简介以及mysql和redis的部署
- 2022.2.21显示器连接器引脚信号定义1
- 吴恩达深度学习笔记7-Course2-Week3【超参数调试、Batch 正则化和程序框架】
- 怎么判断linux22端口是否通,在Linux环境下使用SSH判断端口是否通(示例代码)
- Linux工作笔记-RabbitMQ的安装
- 古风手机壁纸,国潮的你不可错过!
- selenium-webdriver自动化测试工具
- 读书后对PMP的理解
- conda h5py_修改conda安装路径
- Boost Asio 使用技巧
- 通过python实现txt中,字母概率的计算,以及信源熵的计算,并且输出
- HD TUNE以及所有其他硬盘检测工具都不能使用的情况
- UE4-手工调整基本姿势
- 一种分数微分基方法用于多尺度纹理增强(Fractional Differential Mask: A Fractional Differential-Based Approach for Multi)
- 复数值神经网络matlab,学界 | Yoshua Bengio等提出深度复数网络:用复数构建深度神经网络(已开源)...
- 影视后期制作学习(AE)(父子级链接-表达式)
- WinRAR 压缩文件的时候排除指定的目录文件夹
- win7/win10下KiWi Syslog服务器的安装与配置
热门文章
- C++中有了malloc/free 为什么还要new/delete?
- tar 打包、压缩和备份
- requests库学习
- 21天Jmeter打卡Day18 前置处理器_熟悉常用组件
- 软件测试从业者,Linux知识从入门到玩转(必读)
- linux xampp图形界面,linux下安装xampp,XAMPP目录结构
- MySQL数值型超出范围_MySQL 数值类型溢出处理
- 免校准的电量计量芯片_交直流两用计量芯片HLW8112
- 欧洲英语语言c1证书,威尼斯大学认可的英语语言证书
- 动态展开所有_动态演示立方体的展开,并且显示11种展开图——GeoGebra制作教程...