【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不知道如何解决时,就只好向 ...
随机推荐
- Nancy异步用法
个人笔记,记录Nancy异步用法 基类,所有请求都将首先执行该类,并执行Before事件 namespace CxyAdvert.Base { public class BaseNancyModel ...
- item 6: 当auto推导出一个不想要的类型时,使用显式类型初始化的语法
本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 Item 5解释了比起显式指定类型,使用auto来 ...
- TCP服务端开发为例--web开发不同url请求为何会走不同方法
拿java的web开发为例子,相信有很多小伙伴是做j2EE开发的,htpp请求,json数据传输都是工作中经常用的,查询请求,添加请求,修改请求前端配个url,例如https://localhost/ ...
- Awesome Python,Python的框架集合
Awesome Python A curated list of awesome Python frameworks, libraries and software. Inspired by awes ...
- Sql_join left right
1.内连接inner join 只返回两张表中所有满足连接条件的行,即使用比较运算符根据每个表中共有的列的值匹配两个表中的行.(inner关键字是可省略的) ①传统的连接写法: 在FROM子句中列出所 ...
- 快速零配置迁移 API 适配 iOS 对 IPv6 以及 HTTPS 的要求
本文快速分享一下快速零配置迁移 API 适配 iOS 对 IPv6 以及 HTTPS 的要求的方法,供大家参考. 原文发表于我的技术博客 零配置方案 最新的苹果审核政策对 API 的 IPv6 以及 ...
- 《Linux内核设计与实现》读书笔记 1&2
第一章 Linux内核简介 1.2追寻Linus足迹:linux简介 Linus开发.Linux是类Unix系统.Linux内核也是自由软件. 1.3操作系统和内核简介 操作系统:在整个系统中负 ...
- 程序设计第三次作业---C++计算器雏形
Github链接:https://github.com/Wasdns/object-oriented 题目:程序设计第三次作业 程序设计第三次作业附加 我的程序设计第三次作业附加 代码规范 更新时间: ...
- Linux系统知识汇总
1 系统相关 1.1 静态IP地址配置 Ubuntu配置和修改IP地址 1.2 Linux内核升级和降级 内核升级 Linux升级内核的正确姿势 内核降级 Ubuntu 16.04 内核降级 1.3 ...
- opencv学习笔记(五)
线性滤波 方框滤波--boxblur函数 均值滤波(邻域平均滤波)--blur函数 高斯滤波--GaussianBlur函数 中值滤波--medianBlur函数 双边滤波--bilateralFil ...