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的所有 ...
随机推荐
- Part 11 Search filter in AngularJS
As we type in the search textbox, all the columns in the table must be searched and only the matchin ...
- PHP 创建重用数据库连接函数 mysqli与PDO
代码如下: 有兴趣的可以测试下 摘自于某书 <? php public function dbConnect( $usertype, $connectionType = 'mysqli' ) { ...
- MYSQL多实例配置与使用教程
原文http://www.111cn.net/database/mysql/58651.htm 在实际的开发过程中,可能会需要在一台服务器上部署多个MYSQL实例,那建议使用MYSQL官方的解决方案 ...
- 使用命令修改ip地址
简述:以serverv 2012 r2为例 常用的几种,当然不全,希望能较快的速率记下一种便可 直接配置 1. 查看网卡的显示名称 2. 配置静态iP地址 3. 查看配置 ...
- Java关键字及其作用
Java关键字及其作用 一. 关键字总览 访问控制 private protected public 类,方法和变量修饰符 abstract class extends fin ...
- 推荐最近使用的一个APP
最近使用一个APP叫做得到,觉得很不错,将一些很好的思想提炼出来,然后语音表达,放松眼睛,聆听收获.
- 如何查找在CDN下的真实ip
今天去找了一下www.bilibili.tv的IP(为什么要这样子做见),发现www.bilibili.tv使用了CDN服务直接ping找不到其真实IP(实际上不用找也可以但就是想找一下). 那我们应 ...
- Python深拷贝和浅拷贝
1- Python引用计数[1] 1.1 引用计数机制 引用计数是计算机编程语言中的一种内存管理技术,是指将资源(可以是对象.内存或磁盘空间等等)的被引用次数保存起来,当被引用次数变为零时就将其释放的 ...
- zedboard U盘挂载+交叉编译helloworld
交叉编译环境见http://blog.csdn.net/xiabodan/article/details/22717175 1:编写hello.c文件 #include<stdio.h> ...
- WCF 配置文件(三)
配置文件概述 WCF服务配置是WCF服务编程的主要部分.WCF作为分布式开发的基础框架,在定义服务以及定义消费服务的客户端时,都使用了配置文件的方法.虽然WCF也提供硬编程的方式,通过在代码中直接设置 ...