bzoj 3529
非常好的一道莫比乌斯反演题,对提升自己的能力有很大帮助。
首先我们分析一下题意:题意让我们求,其中
那么我们首先对后面的式子进行一下变形,变形过程详见https://blog.csdn.net/lleozhang/article/details/89093689
于是最后变成了这个样子:
但是这个式子还是不好,所以我们改变一下枚举顺序,先枚举d
于是上式改为:
可以发现右侧的式子是一个反演的形式,于是记
于是原式=
先预处理出每个数的约数和(线性筛),然后利用数论分块+前缀和计算即可
等等,难道就这么简单?
当然不会了!!!
再仔细想想,我们上面的过程根本没有管a啊!
由于对k是有要求的,所以我们在预处理的时候如果不知道询问中的a,就没有办法确认对于每个d,哪个k是可用的!
那怎么办?
离线!
我们先将所有询问按照a从小到大排序,这样前面的询问所能用到的k后面的询问一定也可以用,这样我只需要每次将因为a变大而变得可用的k加入即可!
可是我们的要求是,所以仅仅对a排序是不够的,由于约数和并不具有单调性,所以我们还要对约数和排序,然后对于每个询问,将新变得合法的k对应地累计进f(d)就可以了
由于这是一个动态的过程,使用树状数组维护f的前缀和,这样就既支持修改,又支持求前缀和了。
贴代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ll long long
#define mode (1ll<<31)
using namespace std;
struct Ques
{
int n,m,a,num;
}q[100005];
int pri[100005];
bool used[100005];
int mu[100005];
struct SIG
{
ll si;
int num;
}sig[100005];
int mi[100005];
ll v[100005];
ll ret[100005];
int s[100005];
int cnt=0;
int lowbit(int x)
{
return x&(-x);
}
void ins(int x,ll y)
{
while(x<=100000)
{
s[x]+=y;
x+=lowbit(x);
}
}
int get_sum(int x)
{
int ans=0;
while(x)
{
ans+=s[x];
x-=lowbit(x);
}
return ans;
}
ll pow_mul(ll x,int y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans*=(ll)x;
}
x*=x;
y/=2;
}
return ans;
}
void init()
{
mu[1]=1;
sig[1].si=1;
sig[1].num=1;
for(int i=2;i<=100000;i++)
{
if(!used[i])
{
pri[++cnt]=i;
mu[i]=-1;
sig[i].si=i+1;
sig[i].num=i;
v[i]=i+1;
mi[i]=1;
}
for(int j=1;j<=cnt&&i*pri[j]<=100000;j++)
{
used[i*pri[j]]=1;
if(i%pri[j]==0)
{
mu[i*pri[j]]=0;
ll temp=v[i]+pow_mul(pri[j],mi[i]+1);
sig[i*pri[j]].si=sig[i].si/v[i]*temp;
sig[i*pri[j]].num=i*pri[j];
mi[i*pri[j]]=mi[i]+1;
v[i*pri[j]]=temp;
break;
}
mu[i*pri[j]]=-mu[i];
sig[i*pri[j]].si=sig[i].si*(pri[j]+1);
sig[i*pri[j]].num=i*pri[j];
v[i*pri[j]]=pri[j]+1;
mi[i*pri[j]]=1;
}
}
}
bool cmp(Ques x,Ques y)
{
return x.a<y.a;
}
bool cmp1(SIG x,SIG y)
{
return x.si<y.si;
}
int solve(int x,int y)
{
if(x>y)
{
swap(x,y);
}
int ans=0;
int last=0;
for(int i=1;i<=x;i=last+1)
{
last=min(x/(x/i),y/(y/i));
ans+=(get_sum(last)-get_sum(i-1))*(x/i)*(y/i);
}
return ans;
}
int T;
inline int read()
{
int f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
T=read();
init();
int maxn=0;
for(int i=1;i<=T;i++)
{
q[i].n=read(),q[i].m=read(),q[i].a=read();
q[i].num=i;
maxn=max(maxn,max(q[i].n,q[i].m));
}
sort(q+1,q+T+1,cmp);
sort(sig+1,sig+100001,cmp1);
int las=1;
for(int i=1;i<=T;i++)
{
while(sig[las].si<=q[i].a&&las<=100000)//枚举k
{
for(int j=1;j*sig[las].num<=maxn;j++)//枚举倍数
{
ins(j*sig[las].num,sig[las].si*mu[j]);
}
las++;
}
ret[q[i].num]=solve(q[i].n,q[i].m)&2147483647;
}
for(int i=1;i<=T;i++)
{
printf("%d\n",ret[i]);
}
return 0;
}
bzoj 3529的更多相关文章
- 【莫比乌斯反演】关于Mobius反演与gcd的一些关系与问题简化(bzoj 2301 Problem b&&bzoj 2820 YY的GCD&&BZOJ 3529 数表)
首先我们来看一道题 BZOJ 2301 Problem b Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd( ...
- 【BZOJ 3529】 [Sdoi2014]数表 (莫比乌斯+分块+离线+树状数组)
3529: [Sdoi2014]数表 Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有 ...
- BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]
3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1399 Solved: 694[Submit][Status] ...
- BZOJ 3529 数表(莫比乌斯反演)
http://www.lydsy.com/JudgeOnline/problem.php?id=3529 思路:令F(i)为i的约数和, 1<=x<=n,1<=y<=m G(i ...
- bzoj 3529 数表
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3529 题目大意:令F(i)为i的约数和,多次询问对于1<=x<=n,1< ...
- ●BZOJ 3529 [Sdoi2014]数表
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3529 题解: 莫比乌斯反演. 按题目的意思,令$f(i)$表示i的所有约数的和,就是要求: ...
- BZOJ 3529 数表(莫比乌斯+树状数组)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3529 题意:有一张n×m的数表,其第i行第j列的数值为能同时整除i和j的所有自然数 ...
- bzoj 3529: [Sdoi2014]数表
#include<cstdio> #include<iostream> #include<algorithm> #define M 200009 //#define ...
- 【BZOJ 3529】【SDOI 2014】数表
看Yveh的题解,这道题卡了好长时间,一直不明白为什么要······算了当时太naive我现在都不好意思说了 #include<cstdio> #include<cstring> ...
- bzoj 3529 数表 莫比乌斯反演+树状数组
题目大意: 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. ...
随机推荐
- .Net Core 配置文件appsettings
1.配置文件为appsettings 在appsettings添加ConnectionStrings: { "Logging": { "IncludeScopes&quo ...
- 委托(作用:解耦),lambda的演化
1.了解委托 MyDelegate类代码如下: using System; using System.Collections.Generic; using System.Linq; using Sys ...
- 解决 Qt5 报错 This application failed to start because it could not find or load the Qt platform plugin
QT为了简化生成发布版本,特别提供了工具 "windeplayqt.exe",这个工具在 "...\Qt5.8.0\5.8\msvc2015_64\bin"的目 ...
- openstack Q版部署-----安装报错问题
1.实例开机提示找不到磁盘Booting from Hard Disk... GRUB. 开启 CPU 虚拟化支持. 将计算节点 nova.conf 配置修改如下即可: [libvirt] cpu_m ...
- 第五节,损失函数:MSE和交叉熵
损失函数用于描述模型预测值与真实值的差距大小,一般有两种比较常见的算法——均值平方差(MSE)和交叉熵. 1.均值平方差(MSE):指参数估计值与参数真实值之差平方的期望值. 在神经网络计算时,预测值 ...
- MySQL绿色版安装整套流程
https://www.cnblogs.com/LiuChunfu/p/6426918.html
- activemq学习笔记2
基本步骤: ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616"); ...
- kali linux 安装 matlab2016Rb
分享安装包: https://pan.baidu.com/s/1hrBd3Li 密码:u9q3 由于Linux版的分为两个镜像,需要挂载后合并: mount R2016b_glnxa64_dvd1.i ...
- WinRAR代码执行漏洞CVE-2018-20250
0x01 分析思路 利用https://github.com/googleprojectzero/winafl 漏洞分析框架模糊测试WinRAR. 几个存档格式的崩溃,例如RAR,LZH和ACE,这些 ...
- 【转】MySQL— 进阶
[转]MySQL— 进阶 目录 一.视图 二.触发器 三.函数 四.存储过程 五.事务 一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需 ...