BZOJ 4815 CQOI2017 小Q的表格 欧拉函数+分块
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4815
题意概述:要认真概述的话这个题就出来了。。。
分析:
首先分析题目,认真研究一下修改操作,想到一个问题:满足什么样的条件的格子会互相影响?
看到式子,一想,这正是辗转相除?迅速意识到行列的gcd相同的格子会互相影响。
然后我们再利用一下系数的关系,把式子变成f(a,a+b)/(a+b)=f(a,b)/b,发现当行相同的时候格子之间的值与所处列数成正比关系,因为题目保证了f(a,b)=f(b,a),同样的性质也会出现在列相同的情况下。对于任意两个互相影响的格子,都可以先变换行坐标再变换列坐标互相到达,于是有:f(a,b)/(a*b)=f(x,y)/(x*y)。
然后你发现有了这个性质,我们就可以用一维空间来储存所有的格子的值了~
令gcd(i,j)=g,那么f(i,j)=f(g,g)*(i*j)/(g*g)。我们令f(g)=f(g,g),所有格子(i,j)的值都可以由f(gcd(i,j))得到。
所以有:
我们令:
,则
考虑一下s(x)的计算,我们枚举i,然后枚举所有小于i的j,如果i,j互质,我们就统计进入答案,可以看成是统计所有小于i且与i互质的j的和乘以i统计进入答案,根据对称性,另一半方阵是一样的,单独处理对角线上的唯一有贡献的(1,1)即可。
有一个神奇的公式:小于i且和i互质的正整数的和为phi(i)*i/2(证明:对于一个小于i的x,gcd(i,x)=1,有gcd(i,i-x)=1,也就是说小于i且与i互质的数是成对出现的,并且每一对的和为i,一共有phi(i)/2对)。(对s(x)的计算也可以莫比乌斯反演,借助[gcd(i,j)==1]=[sum{ mu(k) | k|i,k|j,即k|gcd(i,j) }==1],但是我只探索出了70分的世界线......)
所以:
,可以直接预处理出来。
最后我们只要用一个分块支持O(sqrt(n))修改,O(1)查询,加上用O(sqrt(k))枚举k的约数就可以做到每组询问O(sqrt(n)+sqrt(k))的时间回答了(有的时候分块的O(1)询问是个很棒的东西,弄个树状数组就自寻烦恼了,分块有点小细节,一定要把f(x)的值原原本本地存起来,不能取模)。
时间复杂度O(M(sqrt(N)+sqrt(K)))。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int MAXN=;
const int mo=;
typedef long long LL; int M,N,K;
int pri[MAXN],tot,phi[MAXN],s[MAXN];
bool ntp[MAXN];
struct Block{
static const int maxn=;
static const int size=;
static const int maxm=;
int sum[maxn],flag[maxm],L[maxm],R[maxm],cnt,sz,belong[maxn];
LL f[maxn];
Block(){ sz=; }
void build(int n){
for(sz=;sz+size<n;sz+=size){
cnt++,L[cnt]=sz,R[cnt]=sz+size;
for(int j=L[cnt];j<R[cnt];j++)
f[j]=1ll*j*j,sum[j]=(sum[j-]+f[j]%mo)%mo,belong[j]=cnt;
flag[cnt]=;
}
cnt++,L[cnt]=sz,R[cnt]=n+;
for(int j=L[cnt];j<R[cnt];j++)
f[j]=1ll*j*j,sum[j]=(sum[j-]+f[j]%mo)%mo,belong[j]=cnt;
flag[cnt]=;
sz=n;
}
void update(int p,LL v){
int delt=((v-f[p])%mo+mo)%mo;
f[p]=v;
for(int i=p;i<R[belong[p]];i++)
sum[i]=(sum[i]+delt)%mo;
for(int i=belong[p]+;i<=cnt;i++)
flag[i]=(flag[i]+delt)%mo;
}
int query(int p){
return (sum[p]+flag[belong[p]])%mo;
}
}block; void ready()
{
ntp[]=ntp[]=,phi[]=;
for(int i=;i<=N;i++){
if(!ntp[i]) pri[++tot]=i,phi[i]=i-;
for(int j=;j<=tot&&1ll*pri[j]*i<=N;j++){
ntp[pri[j]*i]=;
if(i%pri[j]==){
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
phi[i*pri[j]]=phi[i]*(pri[j]-);
}
}
block.build(N);
for(int i=;i<=N;i++)
s[i]=(s[i-]+1ll*i*i%mo*phi[i]%mo)%mo;
}
int gcd(int x,int y){ return !y?x:gcd(y,x%y); }
void work()
{
scanf("%d%d",&M,&N);
ready();
int a,b,k,p,ans,d; LL x;
for(int i=;i<=M;i++){
scanf("%d%d%lld%d",&a,&b,&x,&k);
p=gcd(a,b);
block.update(p,x/(a/p)/(b/p));
ans=;
for(int g=,last;g<=k;g=last+){
last=k/(k/g);
d=((block.query(last)-block.query(g-))%mo+mo)%mo;
ans=(ans+1ll*s[k/g]*d%mo)%mo;
}
printf("%d\n",ans);
}
}
int main()
{
work();
return ;
}
BZOJ 4815 CQOI2017 小Q的表格 欧拉函数+分块的更多相关文章
- BZOJ 4815 [Cqoi2017]小Q的表格 ——欧拉函数
把式子化简一波. 发现一个比较厉害的性质:每个点只能影响到行列下标$gcd$与它相同的点. 然后就可以计算$\sum_{g<=k}f(g,g)*\sum_{i<=k}\sum_{j< ...
- bzoj 4815: [Cqoi2017]小Q的表格 [数论]
4815: [Cqoi2017]小Q的表格 题意: 单点修改,查询前缀正方形和.修改后要求满足条件f(a,b)=f(b,a), b×f(a,a+b)=(a+b)*f(a,b) 一开始sb了认为一次只会 ...
- bzoj 4815: [Cqoi2017]小Q的表格【欧拉函数+分块】
参考:http://blog.csdn.net/qq_33229466/article/details/70174227 看这个等式的形式就像高精gcd嘛-所以随便算一下就发现每次修改(a,b)影响到 ...
- bzoj 4815 [Cqoi2017]小Q的表格——反演+分块
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4815 大概就是推式子的时候注意有两个边界都是 n ,考虑变成 2*... 之类的. 分块维护 ...
- 【BZOJ】2005: [Noi2010]能量采集(欧拉函数+分块)
http://www.lydsy.com/JudgeOnline/problem.php?id=2005 首先和某题一样应该一样可以看出每个点所在的线上有gcd(x,y)-1个点挡着了自己... 那么 ...
- 4815: [Cqoi2017]小Q的表格 莫比乌斯反演 分块
(Updated 2018.04.28 : 发现公式效果不好,重新处理图片)国际惯例的题面:看到这两个公式,很多人都会想到与gcd有关.没错,最终的结论就是f(a,b)=f(gcd(a,b))*(a/ ...
- [BZOJ4815][CQOI2017]小Q的表格(莫比乌斯反演)
4815: [Cqoi2017]小Q的表格 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 832 Solved: 342[Submit][Statu ...
- 【BZOJ4815】[CQOI2017]小Q的表格(莫比乌斯反演,分块)
[BZOJ4815][CQOI2017]小Q的表格(莫比乌斯反演,分块) 题面 BZOJ 洛谷 题解 神仙题啊. 首先\(f(a,b)=f(b,a)\)告诉我们矩阵只要算一半就好了. 接下来是\(b* ...
- 洛咕 P3700 [CQOI2017]小Q的表格
洛咕 P3700 [CQOI2017]小Q的表格 神仙题orz 首先推一下给的两个式子中的第二个 \(b\cdot F(a,a+b)=(a+b)\cdot F(a,b)\) 先简单的想,\(F(a,a ...
随机推荐
- Python字符串必记函数
Python字符串函数数不胜数,想要记完所有几乎不可能,下列几个是极为重要的一些函数,属于必记函数. 一.join 功能: 将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串 语 ...
- [SHELL]软件管理
- vue中将html字符串转换成html后的一些问题
今天整理之前做vue项目时遇到的一些问题,发现了当时遇到的一个很小但是又会引出很多问题的一个问题(总之就是很有意思,听我慢慢给你到来),这个问题就是当时处理后端数据时,如何将后端返回来的字符串转换成h ...
- vscode vue 项目保存运行lint进行代码修正
{ "editor.tabSize": 2, "files.associations": { "*.vue": "vue" ...
- 自定义注解实现(spring aop)
1.基本概念 1.1 aop 即面向切面编程,优点是耦合性低,能使业务处理和切面处理分开开发,扩展和修改方面,当引入了注解方式时,使用起来更加方便. 1.2 应用场景 打日志.分析代码执行时间.权限控 ...
- php无限级分类----封装函数
public function catetree($cateRes){//传递过来的数据资源 return $this->sort($cateRes); 调用函数 } public functi ...
- Python学习手册之正则表达式示例--邮箱地址提取
在上一篇文章中,我们介绍了 Python 的捕获组和特殊匹配字符串,现在我们介绍 Python 的正则表达式使用示例.查看上一篇文章请点击:https://www.cnblogs.com/dustma ...
- 动态的GRE OVER IPSEC的实验模拟与分析
此篇博客正在介绍的是下图中的Dynamic P2P GRE OVER IPSEC VPN: 为什么出现这种动态的GRE OVER IPSEC VPN技术呢? 首先在前面几篇博客中已经介绍过了,动态是为 ...
- 谁能笑到最后,约瑟夫环-Josephus问题求解
一. 简述Josephus问题 N个人站成一环,从1号开始,用刀将环中后面一个人“消灭“”掉,之后再将刀递给下一个人,这样依次处理,最后留下一个幸存者. 二. 求解方法 1. 约瑟夫问题如果使用 ...
- C语言#ifdef等宏的妙用
这几个宏是为了进行条件编译.一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”.有时,希望当满足某条件 ...