【BZOJ4815】[CQOI2017]小Q的表格(莫比乌斯反演,分块)
【BZOJ4815】[CQOI2017]小Q的表格(莫比乌斯反演,分块)
题面
题解
神仙题啊。
首先\(f(a,b)=f(b,a)\)告诉我们矩阵只要算一半就好了。
接下来是\(b*f(a,a+b)=(a+b)*f(a,b)\)
这个式子怎么看呢?
\]
这个式子很明显类似于辗转相减的式子,如果我们令\(c=(a+b)\),那么等式就可以写成
\]
那么进一步,意味着我们可以写成辗转相除的式子。
\]
所以,类似于求\(gcd\)的终止状态,我们可以利用这个写出一个等式:
\]
为了方便后面直接令\(d=gcd(a,b)\),即等式为
\]
那么,不难发现,单次的修改只会对于\(d\)相等的位置产生影响。
考虑\(ans\)是个啥玩意
\]
后面一半的式子可以用莫比乌斯反演直接计算值。
当然了,也可以这样子推:
\]
后面那一步化简简单证明一下,假设\(x\)与\(n\)互质,那么\(n-x\)也与\(n\)互质,因此所有与\(n\)互质的数的和是两两配对的。
也就是后面这一部分是可以提前预处理出来的,因为是\(k/d\),也就是等价于可以数论分块,所以我们现在唯一要做的就是维护\(f(i,i)\)的前缀和。
而修改操作显然是把当前位置会影响的位置的值全部对应的扩倍。也就是会影响到\(f(gcd,gcd)\)这个位置的值。我们要找个方法快速计算\(f(i,i)\)的前缀和。
考虑数据范围,操作次数很少,但是操作的范围很大。单次询问的时候我们有一个\(\sqrt k\)的数论分块的复杂度,也就是\(2*10^3\),操作次数有\(10^4\),所以我们显然不能带\(log\)的计算前缀和。那么考虑分块,将计算前缀和的复杂度将至\(O(1)\),而修改复杂度变为\(O(\sqrt n)\)。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MOD 1000000007
#define MAX 4000400
#define BLK 2200
inline ll read()
{
ll x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int fpow(int a,int b)
{
int s=1;
while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}
return s;
}
int phi[MAX],pri[MAX],tt,s[MAX];
bool zs[MAX];
void Pre(int n)
{
phi[1]=1;
for(int i=2;i<=n;++i)
{
if(!zs[i])pri[++tt]=i,phi[i]=i-1;
for(int j=1;j<=tt&&i*pri[j]<=n;++j)
{
zs[i*pri[j]]=true;
if(i%pri[j])phi[i*pri[j]]=phi[i]*(pri[j]-1);
else{phi[i*pri[j]]=phi[i]*pri[j];break;}
}
}
for(int i=1;i<=n;++i)s[i]=1ll*i*i%MOD*phi[i]%MOD;
for(int i=1;i<=n;++i)s[i]=(s[i]+s[i-1])%MOD;
}
int pre[BLK],ps[BLK],bs[BLK][BLK],val[MAX];
int b[MAX],tot,blk;
int n,m;
int Query(int x){if(!x)return 0;return (pre[b[x]-1]+bs[b[x]][x-blk*(b[x]-1)])%MOD;}
void Modify(int x,int w)
{
val[x]=w;int p=x-blk*(b[x]-1);
for(int i=x;b[i]==b[x];++i,++p)
bs[b[x]][p]=(bs[b[x]][p-1]+val[i])%MOD;
ps[b[x]]=bs[b[x]][p-1];
for(int i=1;i<=tot;++i)pre[i]=(pre[i-1]+ps[i])%MOD;
}
int Calc(int k)
{
int ret=0;
for(int i=1,j;i<=k;i=j+1)
{
j=k/(k/i);
ret=(ret+1ll*(Query(j)-Query(i-1)+MOD)*s[k/i])%MOD;
}
return ret;
}
int main()
{
m=read();n=read();Pre(n);blk=sqrt(n);
for(int i=1;i<=n;++i)b[i]=(i-1)/blk+1;
tot=b[n];
for(int i=1;i<=n;++i)val[i]=1ll*i*i%MOD;
for(int i=1;i<=tot;++i)
for(int j=1,a=(i-1)*blk+1;j<=blk&&a<=n;++j,++a)
ps[i]=(ps[i]+val[a])%MOD,bs[i][j]=(bs[i][j-1]+val[a])%MOD;
for(int i=1;i<=tot;++i)pre[i]=(pre[i-1]+ps[i])%MOD;
while(m--)
{
int a=read(),b=read(),x=read()%MOD,k=read();
int d=__gcd(a,b);
Modify(d,1ll*x*d%MOD*d%MOD*fpow(1ll*a*b%MOD,MOD-2)%MOD);
printf("%d\n",Calc(k));
}
return 0;
}
【BZOJ4815】[CQOI2017]小Q的表格(莫比乌斯反演,分块)的更多相关文章
- [BZOJ4815][CQOI2017]小Q的表格(莫比乌斯反演)
4815: [Cqoi2017]小Q的表格 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 832 Solved: 342[Submit][Statu ...
- 4815: [Cqoi2017]小Q的表格 莫比乌斯反演 分块
(Updated 2018.04.28 : 发现公式效果不好,重新处理图片)国际惯例的题面:看到这两个公式,很多人都会想到与gcd有关.没错,最终的结论就是f(a,b)=f(gcd(a,b))*(a/ ...
- BZOJ4815 [CQOI2017]小Q的表格 【数论 + 分块】
题目链接 BZOJ4815 题解 根据题中的式子,手玩一下发现和\(gcd\)很像 化一下式子: \[ \begin{aligned} bf(a,a + b) &= (a + b)f(a,b) ...
- [bzoj4815]: [Cqoi2017]小Q的表格
来自FallDream的博客,未经允许,请勿转载,谢谢. 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理.每当小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了认为一次只会 ...
- 洛咕 P3700 [CQOI2017]小Q的表格
洛咕 P3700 [CQOI2017]小Q的表格 神仙题orz 首先推一下给的两个式子中的第二个 \(b\cdot F(a,a+b)=(a+b)\cdot F(a,b)\) 先简单的想,\(F(a,a ...
- [bzoj4815] [洛谷P3700] [Cqoi2017] 小Q的表格
Description 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理. 每当小Q不知道如何解决时,就只好向你求助.为了完成任务,小Q需要列一个表格 ...
- bzoj4815[CQOI2017]小Q的格子
题意 不简述题意了,简述题意之后这道题就做出来了.放个原题面. 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理. 每当小Q不知道如何解决时,就只好向 ...
随机推荐
- ASP.NET MVC中jQuery与angularjs混合应用传参并绑定数据
要求是这样子的,在一个列表页中,用户点击详细铵钮,带记录的主键值至另一页.在另一外页中,获取记录数据,然后显示此记录数据在网页上. 先用动图演示: 昨天有分享为ng-click传递参数 <ang ...
- Ionic app 通知在Moto 360 Watch上显示通知(2)
在前一篇文章中,我们已经将Wtach的环境测试成功,下面进入我们自己消息的接收. 1.安装JPush插件在我们的App中,这个具体步骤可以参考 Ionic 安装JPush过程 2.在App上的登录模块 ...
- [转]Linux下安装Java环境配置步骤详述
1.下载jdk8 登录网址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 选择 ...
- Zookeeper Windows版的服务安装和管理工具
以前研究过负载均衡,最近正在项目上实施(从来没做过小项目以上级别的东西,哈).然后遇到了多个一模一样但是同时运行的服务.不同服务但依赖同相同的配置数据(前端网页服务:Nginx+IIS+nodejs. ...
- Flutter - TabBar导航栏切换后,状态丢失
上一篇讲到了 Flutter - BottomNavigationBar底部导航栏切换后,状态丢失 里面提到了TabBar,这儿专门再写一下吧,具体怎么操作,来不让TabBar的状态丢失.毕竟大家99 ...
- jenkins 构建后发送钉钉消息通知(插件)
钉钉,越来越多的公司采用,那么我们在持续集成中,也可以直接选择钉钉插件的,在之前的博客中 ,对发送的钉钉消息进行了定制,那样的话会开启一个新的任务, 其实今天呢,我们可以直接安装一个插件就可以发送了, ...
- Haproxy+Keepalived高可用环境部署梳理(主主和主从模式)
Nginx.LVS.HAProxy 是目前使用最广泛的三种负载均衡软件,本人都在多个项目中实施过,通常会结合Keepalive做健康检查,实现故障转移的高可用功能. 1)在四层(tcp)实现负载均衡的 ...
- Jmeter-使用Stepping Thread Group插件来设置负载场景
前言: 什么是实际的性能测试???1)思考时间:用户在做不同操作之间有时间停顿,或者延迟,思考时间就是模拟用户的操作过程中的停顿的间.2)步伐,速度:主要包括,大量用户进来的时间和退出时间,控制迭代之 ...
- Python基础系列讲解——random模块随机数的生成
随机数参与的应用场景大家一定不会陌生,比如密码加盐时会在原密码上关联一串随机数,蒙特卡洛算法会通过随机数采样等等.Python内置的random模块提供了生成随机数的方法,使用这些方法时需要导入ran ...
- MyBatis中if,where,set标签
<if>标签 <select id="findActiveBlogWithTitleLike" resultType="Blog"> S ...