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的数之和. ...
随机推荐
- php编程 之php基础 表单
1 ,php表单 当处理php表单的时候,php能把来自html页面的表单元素自动变成可供php脚本使用的数据. 比如: <html> <head> <meta char ...
- MySQL绿色版安装整套流程
https://www.cnblogs.com/LiuChunfu/p/6426918.html
- ROC和AUC理解
一. ROC曲线概念 二分类问题在机器学习中是一个很常见的问题,经常会用到.ROC (Receiver Operating Characteristic) 曲线和 AUC (Area Under th ...
- Faster_RCNN 2.模型准备(上)
总结自论文:Faster_RCNN,与Pytorch代码: 本文主要介绍代码第二部分:model/utils , 首先分析一些主要理论操作,然后在代码分析里详细介绍其具体实现. 一. 主要操作 1. ...
- 嵌入式系统C编程之错误处理【转】
转自:http://www.cnblogs.com/clover-toeic/p/3919857.html 前言 本文主要总结嵌入式系统C语言编程中,主要的错误处理方式.文中涉及的代码运行环境如下: ...
- mac使用技巧之截图
1.选定区域截图 command+shift+3 选定区域按住control,可以直接截图到剪切板, 按option可以进行比例缩放. 按住shift可以选定区域 按住空格键可以进入窗口截图模式. 2 ...
- Python3学习笔记31-xlrd模块
xlrd模块是用来读取excel的第三方模块,需要下载安装后才能使用.新建一个excel,随便填充一些数据用来测试下. # -*- coding: utf-8 -*- import xlrd #打 ...
- 题解-Codeforces710F String Set Queries
咕了好久没更博客,最近得知可以去冬眠营玩耍,还可以搭顺风车回广州过年 (最近做到的比较有意思的题目:bzoj3958.hihocoder1419) Problem Codeforces-710F--洛 ...
- 花神的数论题(这题...哎。数位dp咋就这么 not naive 呢)
题意简介 没什么好说,就是让你求出 1 ~ n 之间每个数转化为二进制后 '1' 的个数,然后乘起来输出积 题目分析 emmmm.... 两种解法(同是 $O(\log^2 N)$ 的算法,组合数效率 ...
- 用Cordova打包Vue-vux项目
技术搭建:vue + vux 首先推荐阅读这篇文章,写的已经很详细了:https://www.jianshu.com/p/25d797b983cd 此处记录下我按照这篇文章打包的时候报的一些错误,方便 ...