【BZOJ4815】[CQOI2017]小Q的表格(莫比乌斯反演,分块)

题面

BZOJ

洛谷

题解

神仙题啊。

首先\(f(a,b)=f(b,a)\)告诉我们矩阵只要算一半就好了。

接下来是\(b*f(a,a+b)=(a+b)*f(a,b)\)

这个式子怎么看呢?

\[\begin{aligned}b*f(a,a+b)&=(a+b)*f(a,b)\\\frac{f(a,a+b)}{a+b}&=\frac{f(a,b)}{b}\\\frac{f(a,a+b)}{a*(a+b)}&=\frac{f(a,b)}{a*b}\end{aligned}
\]

这个式子很明显类似于辗转相减的式子,如果我们令\(c=(a+b)\),那么等式就可以写成

\[\frac{f(a,c)}{a*c}=\frac{f(a,c-a)}{a*(c-a)}
\]

那么进一步,意味着我们可以写成辗转相除的式子。

\[\frac{f(a,b)}{a*b}=\frac{f(a,a\%b)}{a*(a\%b)}
\]

所以,类似于求\(gcd\)的终止状态,我们可以利用这个写出一个等式:

\[\frac{f(a,b)}{a*b}=\frac{f(gcd(a,b),gcd(a,b)}{gcd^2(a,b)}
\]

为了方便后面直接令\(d=gcd(a,b)\),即等式为

\[f(a,b)=\frac{a*b}{d^2}f(d,d)
\]

那么,不难发现,单次的修改只会对于\(d\)相等的位置产生影响。

考虑\(ans\)是个啥玩意

\[\begin{aligned}ans&=\sum_{i=1}^k\sum_{j=1}^kf(i,j)\\&=\sum_{d=1}^kf(d,d)\sum_{i=1}^k\sum_{j=1}^k\frac{i*j}{d^2}[gcd(i,j)=d]\\&=\sum_{d=1}^kf(d,d)\sum_{i=1}^{k/d}\sum_{j=1}^{k/d}ij[gcd(i,j)=1]\end{aligned}
\]

后面一半的式子可以用莫比乌斯反演直接计算值。

当然了,也可以这样子推:

\[\begin{aligned}\sum_{i=1}^n\sum_{j=1}^nij[gcd(i,j)=1]&=2*\sum_{i=1}^ni\sum_{j=1}^ij[gcd(i,j)=1]\\&=2*\sum_{i=1}^n\frac{i\varphi(i)}{2}\\&=\sum_{i=1}^ni^2\varphi(i)\end{aligned}
\]

后面那一步化简简单证明一下,假设\(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的表格(莫比乌斯反演,分块)的更多相关文章

  1. [BZOJ4815][CQOI2017]小Q的表格(莫比乌斯反演)

    4815: [Cqoi2017]小Q的表格 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 832  Solved: 342[Submit][Statu ...

  2. 4815: [Cqoi2017]小Q的表格 莫比乌斯反演 分块

    (Updated 2018.04.28 : 发现公式效果不好,重新处理图片)国际惯例的题面:看到这两个公式,很多人都会想到与gcd有关.没错,最终的结论就是f(a,b)=f(gcd(a,b))*(a/ ...

  3. BZOJ4815 [CQOI2017]小Q的表格 【数论 + 分块】

    题目链接 BZOJ4815 题解 根据题中的式子,手玩一下发现和\(gcd\)很像 化一下式子: \[ \begin{aligned} bf(a,a + b) &= (a + b)f(a,b) ...

  4. [bzoj4815]: [Cqoi2017]小Q的表格

    来自FallDream的博客,未经允许,请勿转载,谢谢. 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理.每当小Q不知道如何解决时,就只好向你求助. ...

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

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

  6. bzoj 4815: [Cqoi2017]小Q的表格 [数论]

    4815: [Cqoi2017]小Q的表格 题意: 单点修改,查询前缀正方形和.修改后要求满足条件f(a,b)=f(b,a), b×f(a,a+b)=(a+b)*f(a,b) 一开始sb了认为一次只会 ...

  7. 洛咕 P3700 [CQOI2017]小Q的表格

    洛咕 P3700 [CQOI2017]小Q的表格 神仙题orz 首先推一下给的两个式子中的第二个 \(b\cdot F(a,a+b)=(a+b)\cdot F(a,b)\) 先简单的想,\(F(a,a ...

  8. [bzoj4815] [洛谷P3700] [Cqoi2017] 小Q的表格

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

  9. bzoj4815[CQOI2017]小Q的格子

    题意 不简述题意了,简述题意之后这道题就做出来了.放个原题面. 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理. 每当小Q不知道如何解决时,就只好向 ...

随机推荐

  1. 锁、C#中Monitor和Lock以及区别

    1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取锁之后因为异常,致锁 ...

  2. AnyProxy做App网络流量测试

    前言: AnyProxy是一个开放式的HTTP代理服务器.Github主页:[https://github.com/alibaba/anyproxy]主要特性包括: 基于Node.js,开放二次开发能 ...

  3. 百度之星-1002-list应用

    用stl的list即可,注意...代码的简洁性(被debug伤痛)注意合并时可以手动pop,或者用splice进行合并,不能用merge!!!merge合并是自带排序!!! #include<b ...

  4. #科委外文文献发现系统——导出word模板1.0

    ps:该篇文档由实验室ljg提供. Crowdsourcing 一.             技术简介 Crowdsourcing, a modern business term coined in ...

  5. Daily Scrumming* 2015.12.21(Day 13)

    一.团队scrum meeting照片 大部分成员编译请假,故今天没有开scrum meeting 二.成员工作总结 姓名 任务ID 迁入记录 江昊 无 无 任务说明: 今日准备编译测验,请假 遇到问 ...

  6. sho

    手工编程:hello world 全部用命令行工具和Notepad编辑器,用手工创建并编译一个C的命令行程序:hello world. public class Hello{         publ ...

  7. 搭建ssm的步骤

    搭建SSM的步骤 ----------------------------- 1.创建web工程 2.把SSM做需要的所有jar导入工程中 3.web.xml 1.Springmvc的前端控制器,如果 ...

  8. git使用命令记录

    一,两个概念:1.工作区:你电脑里能看见的目录,比如一个项目文件夹就是一个工作区2.版本库工作区(该项目的文件夹)中有一个隐藏文件 .git ,就是git的版本库.(这个文件默认是隐藏,Ctrl+h ...

  9. CodeIgniter 2.x和3.x修改默认控制器问题解答

    首先明确一点,CodeIgniter框架的2.x和3.x版本中修改默认控制器是有一点区别的 但相同的操作都是修改application/config/routes.php $route['defaul ...

  10. activiti-ldap-integration

    https://stackoverflow.com/questions/19488764/activiti-ldap-integration https://community.alfresco.co ...