非常好的一道莫比乌斯反演题,对提升自己的能力有很大帮助。

首先我们分析一下题意:题意让我们求,其中

那么我们首先对后面的式子进行一下变形,变形过程详见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的更多相关文章

  1. 【莫比乌斯反演】关于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( ...

  2. 【BZOJ 3529】 [Sdoi2014]数表 (莫比乌斯+分块+离线+树状数组)

    3529: [Sdoi2014]数表 Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有 ...

  3. BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]

    3529: [Sdoi2014]数表 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1399  Solved: 694[Submit][Status] ...

  4. BZOJ 3529 数表(莫比乌斯反演)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3529 思路:令F(i)为i的约数和, 1<=x<=n,1<=y<=m G(i ...

  5. bzoj 3529 数表

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3529 题目大意:令F(i)为i的约数和,多次询问对于1<=x<=n,1< ...

  6. ●BZOJ 3529 [Sdoi2014]数表

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3529 题解: 莫比乌斯反演. 按题目的意思,令$f(i)$表示i的所有约数的和,就是要求: ...

  7. BZOJ 3529 数表(莫比乌斯+树状数组)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3529 题意:有一张n×m的数表,其第i行第j列的数值为能同时整除i和j的所有自然数 ...

  8. bzoj 3529: [Sdoi2014]数表

    #include<cstdio> #include<iostream> #include<algorithm> #define M 200009 //#define ...

  9. 【BZOJ 3529】【SDOI 2014】数表

    看Yveh的题解,这道题卡了好长时间,一直不明白为什么要······算了当时太naive我现在都不好意思说了 #include<cstdio> #include<cstring> ...

  10. bzoj 3529 数表 莫比乌斯反演+树状数组

    题目大意: 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. ...

随机推荐

  1. php编程 之php基础 表单

    1 ,php表单 当处理php表单的时候,php能把来自html页面的表单元素自动变成可供php脚本使用的数据. 比如: <html> <head> <meta char ...

  2. MySQL绿色版安装整套流程

    https://www.cnblogs.com/LiuChunfu/p/6426918.html

  3. ROC和AUC理解

    一. ROC曲线概念 二分类问题在机器学习中是一个很常见的问题,经常会用到.ROC (Receiver Operating Characteristic) 曲线和 AUC (Area Under th ...

  4. Faster_RCNN 2.模型准备(上)

    总结自论文:Faster_RCNN,与Pytorch代码: 本文主要介绍代码第二部分:model/utils , 首先分析一些主要理论操作,然后在代码分析里详细介绍其具体实现. 一. 主要操作 1. ...

  5. 嵌入式系统C编程之错误处理【转】

    转自:http://www.cnblogs.com/clover-toeic/p/3919857.html 前言 本文主要总结嵌入式系统C语言编程中,主要的错误处理方式.文中涉及的代码运行环境如下: ...

  6. mac使用技巧之截图

    1.选定区域截图 command+shift+3 选定区域按住control,可以直接截图到剪切板, 按option可以进行比例缩放. 按住shift可以选定区域 按住空格键可以进入窗口截图模式. 2 ...

  7. Python3学习笔记31-xlrd模块

    xlrd模块是用来读取excel的第三方模块,需要下载安装后才能使用.新建一个excel,随便填充一些数据用来测试下. ​ # -*- coding: utf-8 -*- import xlrd #打 ...

  8. 题解-Codeforces710F String Set Queries

    咕了好久没更博客,最近得知可以去冬眠营玩耍,还可以搭顺风车回广州过年 (最近做到的比较有意思的题目:bzoj3958.hihocoder1419) Problem Codeforces-710F--洛 ...

  9. 花神的数论题(这题...哎。数位dp咋就这么 not naive 呢)

    题意简介 没什么好说,就是让你求出 1 ~ n 之间每个数转化为二进制后 '1' 的个数,然后乘起来输出积 题目分析 emmmm.... 两种解法(同是 $O(\log^2 N)$ 的算法,组合数效率 ...

  10. 用Cordova打包Vue-vux项目

    技术搭建:vue + vux 首先推荐阅读这篇文章,写的已经很详细了:https://www.jianshu.com/p/25d797b983cd 此处记录下我按照这篇文章打包的时候报的一些错误,方便 ...