3529: [Sdoi2014]数表 - BZOJ
Description
有一张N×m的数表,其第i行第j列(1 < =i < =n,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
这个太卡时间了,搞了我好久,不过最后跑了8s,利用了他取模的数,C++正好可以直接爆int,然后小于0就加2的31次方就行了,我就用longint强行截取了后半部分相当于爆int
首先a[i,j]上的数我们可以看成是F[gcd(i,j)],F[i]我们都预处理出来
然后我们要求的就是 ΣF[i]*g[i] (F[i]<=a,g[i]是gcd=i的个数)
所以我们要求的就是 ΣF[i]*Σtrunc(n/d)*trunc(m/d)*μ(d/i) (F[i]<=a,i|d)
所以我们要求的就是 Σtrunc(n/d)*trunc(m/d)*ΣF[i]*μ(d/i) (F[i]<=a,i|d)
因为trunc(n/d)*trunc(m/d)只有根号n级别的个数,所以我们要处理ΣF[i]*μ(d/i)的前缀和,我用的是树状数组
然后每次询问都可以根号n*logn回答了
但是还有一个条件,就是F[i]<=a
前缀和还是动态的,怎么办
首先把F[i]排序是肯定的,对于每一个i,影响到的是他的倍数,这个很麻烦啊
于是就离线做了,把a排序,然后暴力修改前缀和,即枚举倍数
因为排序了,所以我们最多每个i都枚举倍数一次,应该是nlognlogn的
然后就写完了
const
maxn=;
h=<<;
type
node=record
n,m,a,id:longint;
end;
var
q:array[..maxn]of node;
flag:array[..maxn]of boolean;
p,u,k,f,ans,c:array[..maxn]of longint;
t,tot,max:longint; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; procedure swap(var x,y:longint);
var
t:longint;
begin
t:=x;x:=y;y:=t;
end; procedure swap(var x,y:node);
var
t:node;
begin
t:=x;x:=y;y:=t;
end; procedure sort(l,r:longint);
var
i,j:longint;
y:int64;
begin
i:=l;
j:=r;
y:=f[k[(l+r)>>]];
repeat
while f[k[i]]<y do
inc(i);
while f[k[j]]>y do
dec(j);
if i<=j then
begin
swap(k[i],k[j]);
inc(i);
dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end; procedure pre;
var
i,j,s:longint;
begin
f[]:=;
u[]:=;
for i:= to max do
begin
if flag[i]=false then
begin
inc(tot);
p[tot]:=i;
f[i]:=i+;
u[i]:=-;
end;
for j:= to tot do
begin
if int64(i)*p[j]>max then break;
flag[i*p[j]]:=true;
if i mod p[j]= then
begin
s:=p[j];
while i mod (int64(s)*p[j])= do
s:=s*p[j];
if s=i then f[i*p[j]]:=(s*p[j]*p[j]-)div(p[j]-)
else f[i*p[j]]:=f[i div s]*f[s*p[j]];
break;
end
else
begin
f[i*p[j]]:=f[i]*(p[j]+);
u[i*p[j]]:=-u[i];
end;
end;
end;
for i:= to max do
k[i]:=i;
sort(,max);
end; procedure sort2(l,r:longint);
var
i,j,y:longint;
begin
i:=l;
j:=r;
y:=q[(l+r)>>].a;
repeat
while q[i].a<y do
inc(i);
while q[j].a>y do
dec(j);
if i<=j then
begin
swap(q[i],q[j]);
inc(i);
dec(j);
end;
until i>j;
if i<r then sort2(i,r);
if j>l then sort2(l,j);
end; procedure init;
var
i:longint;
begin
read(t);
for i:= to t do
begin
read(q[i].n,q[i].m,q[i].a);
q[i].id:=i;
if q[i].n>q[i].m then swap(q[i].n,q[i].m);
if max<q[i].n then max:=q[i].n;
end;
sort2(,t);
end; procedure add(x,y:longint);
begin
while x<= do
begin
c[x]:=longint(int64(c[x])+y);
x:=x+(x and (-x));
end;
end; function sum(x:longint):longint;
begin
sum:=;
while x> do
begin
sum:=longint(int64(sum)+c[x]);
x:=x-(x and (-x));
end;
end; procedure main;
var
i,j,kk,s,lasta,s1,s2:longint;
begin
lasta:=;
for i:= to t do
begin
while (lasta<=max) and (f[k[lasta]]<=q[i].a) do
begin
s:=k[lasta];
j:=;
while s<=max do
begin
if u[j]<> then add(s,f[k[lasta]]*u[j]);
inc(s,k[lasta]);
inc(j);
end;
inc(lasta);
end;
kk:=;
while kk<=q[i].n do
begin
s1:=q[i].n div kk;
s2:=q[i].m div kk;
s:=min(trunc(q[i].n/s1),trunc(q[i].m/s2));
ans[q[i].id]:=longint(int64(ans[q[i].id])+int64(longint(int64(s1)*s2))*longint(int64(sum(s))-sum(kk-)));
kk:=s+;
end;
end;
for i:= to t do
if ans[i]< then writeln(ans[i]+h)
else writeln(ans[i]);
end; begin
init;
pre;
main;
end.
3529: [Sdoi2014]数表 - BZOJ的更多相关文章
- BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]
3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1399 Solved: 694[Submit][Status] ...
- bzoj 3529 [Sdoi2014]数表(莫比乌斯反演+BIT)
Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a ...
- ●BZOJ 3529 [Sdoi2014]数表
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3529 题解: 莫比乌斯反演. 按题目的意思,令$f(i)$表示i的所有约数的和,就是要求: ...
- 【刷题】BZOJ 3529 [Sdoi2014]数表
Description 有一张n×m的数表,其第i行第j列(1<=i<=n,1<=j<=m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. In ...
- BZOJ 3529 [Sdoi2014]数表 (莫比乌斯反演+树状数组+离线)
题目大意:有一张$n*m$的数表,第$i$行第$j$列的数是同时能整除$i,j$的所有数之和,求数表内所有不大于A的数之和 先是看错题了...接着看对题了发现不会做了...刚了大半个下午无果 看了Po ...
- bzoj 3529: [Sdoi2014]数表
#include<cstdio> #include<iostream> #include<algorithm> #define M 200009 //#define ...
- 【BZOJ】3529: [Sdoi2014]数表
题意:求 $$\sum_{i=1}^{n} \sum_{j=1}^{m} \sum_{d|(i, j)} d 且 (\sum_{d|(i, j)} d)<=a$$ n, m<=1e5,q次 ...
- 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 ...
- 【BZOJ 3529】 [Sdoi2014]数表 (莫比乌斯+分块+离线+树状数组)
3529: [Sdoi2014]数表 Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有 ...
随机推荐
- MySQL之建设工程监管信息系统
--创建SelfStudy数据库 CREATE DATABASE ConstructionDB ON PRIMARY --创建主数据库文件 ( NAME=' ConstructionDB', --数据 ...
- JS验证框架(exValidation)
exValidation是一个前台校验框架 能够校验前台的常用的输入错误. 例如,必须输入,用户输入长度...... ----------------------------------------- ...
- 【SNMP】SNMP概述
SNMP概述 SNMP(Simple Network Management Protocol,简单网络管理协议)是目前UDP/IP网络中应用最为广泛的网络管理协议,它提供了一个管理框架来监控和维护互联 ...
- Mysql 格式化日期格式
DATE_FORMAT(date, format) 根据格式串format 格式化日期或日期和时间值date,返回结果串. 可用DATE_FORMAT( ) 来格式化DATE 或DATETIME 值, ...
- JSON字符串和js对象转换
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON js数据类型: 字符串.数字 ...
- DailyWallpaper v1.02 released
上次忘了写软件说明,先补上一个. 软件说明: 每天定时(暂定上午11点)下载美国国家地理网站的photo of the day图片作为桌面壁纸.下载图片会以日期为名称保存在C:\DailyWallpa ...
- 【风马一族_Python】 更替pip的版本
替换电脑上python中的pip的版本 例子: 下载的文件:pip-8.1.1-py2.py3-none-any.whl 下载地址:https://pypi.python.org/pypi/pip/# ...
- 《Apache之访问本地用户家目录》——RHEL6.3
首先保证这个本地用户是系统上有的. 1.安装httpd软件包: Yum install httpd 2.启动apache服务: 3.配置用户的家目录: 4.打开apache访问家目录的权限: 5.配置 ...
- Linux常用命令操作说明(链接)
1. Busybox下tftp命令使用详解 2. Linux中rc的含义 3. <Unix文件系统结构标准>(Filesystem Hierarchy Standard) 4. 用size ...
- PHP性能分析
内容来自以下站点整理http://jingyan.baidu.com/article/ff4116257e0d5112e48237a0.html关于PHP,很多人的直观感觉是PHP是一种灵活的脚本语言 ...