3529: [Sdoi2014]数表

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 1399  Solved: 694
[Submit][Status][Discuss]

Description

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

Input

输入包含多组数据。
    输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据。

Output

对每组数据,输出一行一个整数,表示答案模2^31的值。

Sample Input

2
4 4 3
10 10 5

Sample Output

20
148

HINT

1 < =N.m < =10^5  , 1 < =Q < =2×10^4

Source

Round 1 Day 1


一个位置的答案就是gcd(i,j)的约数和

一个个单独算不好优化不行,从gcd(i,j)的取值方面考虑,因为它的取值就是1...n

设F(i)为i的约数和,f(i)为gcd(x,y)=i的个数,那么答案就是ΣF(i)*f(i)

f(i)上两题用到过,反演后f(i)=Σ{i|d} miu(d/i)*(n/d)*(m/d)

d和i的取值范围相同,可以得到如下式子

现在我们只需要求出g(i)=的前缀和 这个问题就能在O(√n)的时间内出解

F(i)是约数和函数,可以通过线性筛计算,或者直接nlogn暴力枚举倍数,速度差不多

然后和上一题一样,暴力枚举每个i更新它的倍数

那么a的限制如何处理?考虑离线

我们发现对答案有贡献的i只有F(i)<=a的i 那么我们将询问按照a从小到大排序 将F(i)从小到大排序 每次询问将<=a的F(i)按照枚举倍数更新的方式插入 用树状数组来维护g的前缀和  这样枚举倍数logn,每个倍数插入树状数组logn,总共nlog^2n

本题取模有一种好厉害的做法:自然溢出int,最后&0x7FFFFFFF

复杂度O(nlog^2n+q√nlogn)

注意:排序[1,N)的话是sort(a+1,a+N),不要a+N+1.......

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e5+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
struct ques{
int n,m,a,id;
bool operator <(const ques &r)const{return a<r.a;}
}q[N];
int n,m;
int notp[N],p[N],mu[N],minfac[N],t1[N],t2[N];
struct data{
int s,i;
bool operator <(const data &r)const{return s<r.s;}
}sf[N];
void sieve(){
for(int i=;i<N;i++) sf[i].i=i;
mu[]=;
sf[].s=;
for(int i=;i<N;i++){
if(!notp[i]){
p[++p[]]=i,mu[i]=-;
minfac[i]=i;
sf[i].s=i+;
t1[i]=i+;
t2[i]=i;
}
for(int j=,k;j<=p[]&&(k=i*p[j])<N;j++){
notp[i*p[j]]=;
minfac[k]=p[j];
if(i%p[j]==){
mu[i*p[j]]=;
t2[k]=t2[i]*p[j];
t1[k]=t1[i]+t2[k];
sf[k].s=sf[i].s/t1[i]*t1[k];
break;
}
mu[i*p[j]]=-mu[i];
t1[k]=+p[j];
t2[k]=p[j];
sf[k].s=sf[i].s*sf[p[j]].s;
}
}
} int g[N];
inline int lowbit(int x){return x&-x;}
inline void add(int p,int v){for(int i=p;i<N;i+=lowbit(i)) g[i]+=v;}
inline int sum(int p){
int ret=;
for(int i=p;i;i-=lowbit(i)) ret+=g[i];
return ret;
}
void ins(int x){
for(int d=sf[x].i;d<N;d+=sf[x].i) add(d,sf[x].s*mu[d/sf[x].i]);
}
int cal(int n,int m){
int ans=,r=;
if(n>m) swap(n,m);
for(int i=;i<=n;i=r+){
r=min(n/(n/i),m/(m/i));
ans+=(sum(r)-sum(i-))*(n/i)*(m/i);
}
return ans;
}
int ans[N];
int main(int argc, const char * argv[]){
sieve();
sort(sf+,sf+N);//!!!!!
int T=read();
for(int i=;i<=T;i++) q[i].n=read(),q[i].m=read(),q[i].a=read(),q[i].id=i;
sort(q+,q++T);
int now=;
for(int i=;i<=T;i++){
int a=q[i].a;
for(;sf[now].s<=a;now++) ins(now);
ans[q[i].id]=cal(q[i].n,q[i].m)&0x7FFFFFFF;
}
for(int i=;i<=T;i++) printf("%d\n",ans[i]);
return ;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e5+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
struct ques{
int n,m,a,id;
bool operator <(const ques &r)const{return a<r.a;}
}q[N];
int n,m;
int notp[N],p[N],mu[N];
struct data{
int s,i;
bool operator <(const data &r)const{return s<r.s;}
}sf[N];
void sieve(){
mu[]=;
for(int i=;i<=;i++){
if(!notp[i]){
p[++p[]]=i,mu[i]=-;
}
for(int j=,k;j<=p[]&&(k=i*p[j])<=;j++){
notp[k]=;
if(i%p[j]==){
mu[k]=;
break;
}
mu[k]=-mu[i];
}
}
for(int i=;i<=;i++){
sf[i].i=i;
for(int j=;j*i<=;j++) sf[i*j].s+=i;
}
} int g[N];
inline int lowbit(int x){return x&-x;}
inline void add(int p,int v){for(int i=p;i<N;i+=lowbit(i)) g[i]+=v;}
inline int sum(int p){
int ret=;
for(int i=p;i;i-=lowbit(i)) ret+=g[i];
return ret;
}
inline void ins(int x){
for(int d=sf[x].i;d<=;d+=sf[x].i) add(d,sf[x].s*mu[d/sf[x].i]);
}
int cal(int n,int m){
int ans=,r=;
if(n>m) swap(n,m);
for(int i=;i<=n;i=r+){
r=min(n/(n/i),m/(m/i));
ans+=(sum(r)-sum(i-))*(n/i)*(m/i);
}
return ans;
}
int ans[N];
int main(int argc, const char * argv[]){
sieve();
sort(sf+,sf+);
int T=read();
for(int i=;i<=T;i++) q[i].n=read(),q[i].m=read(),q[i].a=read(),q[i].id=i;
sort(q+,q++T);
int now=;
for(int i=;i<=T;i++){
int a=q[i].a;
for(;now<=&&sf[now].s<=a;now++) ins(now);
ans[q[i].id]=cal(q[i].n,q[i].m)&0x7FFFFFFF;
}
for(int i=;i<=T;i++) printf("%d\n",ans[i]);
return ;
}

BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]的更多相关文章

  1. BZOJ 3529 [Sdoi2014]数表 (莫比乌斯反演+树状数组+离线)

    题目大意:有一张$n*m$的数表,第$i$行第$j$列的数是同时能整除$i,j$的所有数之和,求数表内所有不大于A的数之和 先是看错题了...接着看对题了发现不会做了...刚了大半个下午无果 看了Po ...

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

    $ans=\sum_{i=1}^n\sum_{j=1}^n\sigma(gcd(i,j))$ 枚举gcd为d的所有数得到 $ans=\sum_{d<=n}\sigma(d)*g(d)$ $g(d ...

  3. BZOJ 3259 [Sdoi2014]数表 (莫比乌斯反演 + 树状数组)

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

  4. 【BZOJ3529】[Sdoi2014]数表 莫比乌斯反演+树状数组

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

  5. BZOJ3529: [Sdoi2014]数表(莫比乌斯反演 树状数组)

    题意 题目链接 Sol 首先不考虑\(a\)的限制 我们要求的是 \[\sum_{i = 1}^n \sum_{j = 1}^m \sigma(gcd(i, j))\] 用常规的套路可以化到这个形式 ...

  6. luogu3312 [SDOI2014]数表 (莫比乌斯反演+树状数组)

    link \(\sum_{i=1}^n\sum_{j=1}^m[s(\gcd(i,j))\le a]s(\gcd(i,j))\) \(=\sum_{p=1}^ns(p)[s(p)\le a]\sum_ ...

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

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

  8. 【BZOJ3529】【莫比乌斯反演 + 树状数组】[Sdoi2014]数表

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

  9. BZOJ_3529_[Sdoi2014]数表_莫比乌斯反演+树状数组

    Description 有一张 n×m 的数表,其第 i 行第 j 列(1 <= i <= n, 1 <= j <= m)的数值为 能同时整除 i 和 j 的所有自然数之和.给 ...

随机推荐

  1. html5+go+websocket简单实例代码

    这次的就直接发放代码截图吧,应该是用go语言做后台一个简易的聊天,这里没用到什么特别的知识,最朴实的来实现效果,主要目的是分享下h5怎么用websocket,go搭建websocket服务的主要部分. ...

  2. YYModel 源码解读(二)之YYClassInfo.h (3)

    前边3篇介绍了YYClassinfo 文件的组成单元,算是功能的分割,按照业务的设计思想来说,方向应该是相反的 由此引申出我们在设计api的思想其实和项目管理是很类似的----- 一些题外话 1.目的 ...

  3. .NET跨平台之旅:将QPS 100左右的ASP.NET Core站点部署到Linux服务器上

    今天下午我们将生产环境中一个单台服务器 QPS(每秒请求数)在100左右的 ASP.NET Core 站点部署到了 Linux 服务器上,这是我们解决了在 .NET Core 上使用 EnyimMem ...

  4. EF(Entity Framework)系统学习系列

    好久没写博客了,继续开启霸屏模式,好了,废话不多说,这次准备重新系统学一下EF,一个偶然的机会找到了一个学习EF的网站(http://www.entityframeworktutorial.net/) ...

  5. linux终端指令总结

    一直没机会进行linux指令的系统学习,但是工作中总能遇到通过指令操作文件或数据库的情况,总不能一味地依赖后端开发者的帮忙.上任领导说过,要是在同一个地方跌倒,那么你就是傻子.我可不想成为傻子,so, ...

  6. JAVA NIO学习笔记1 - 架构简介

    最近项目中遇到不少NIO相关知识,之前对这块接触得较少,算是我的一个盲区,打算花点时间学习,简单做一点个人学习总结. 简介 NIO(New IO)是JDK1.4以后推出的全新IO API,相比传统IO ...

  7. USB设备(移动硬盘、鼠标)掉电掉驱动的两种解决方案

    症状: 当你发现"移动硬盘图标"经常无故消失,又自己出现时. 你可以把这个现象称之为"掉电" or "掉驱动". 遇到这种情况,相当不爽. ...

  8. 在DevExpress程序中使用Winform分页控件直接录入数据并保存

    一般情况下,我们都倾向于使用一个组织比较好的独立界面来录入或者展示相关的数据,这样处理比较规范,也方便显示比较复杂的数据.不过在一些情况下,我们也可能需要直接在GridView表格上直接录入或者修改数 ...

  9. C#开发微信门户及应用(26)-公众号微信素材管理

    微信公众号最新修改了素材的管理模式,提供了两类素材的管理:临时素材和永久素材的管理,原先的素材管理就是临时素材管理,永久素材可以永久保留在微信服务器上,微信素材可以在上传后,进行图片文件或者图文消息的 ...

  10. jqGrid合并表头

    jqGrid是一款常用的制表软件,最近开发刚好用到.记录一下常用功能留着以后查找顺便发扬一下开源精神. 二级表头是一种经常会碰到的需求,很多时候为了方便查找需要在原有的表头上再加一层,区分表格不同列的 ...