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的所有 ...
随机推荐
- Ionic之顺带APP
1:Ionic简介 官方:我们设计ionic来帮助 web 开发人员能够像开发网站一样开发出强大的移动APP应用. ionic是一个html5开发APP的框架,在开发运行效率可以说是最好的H5框架,把 ...
- yarn.resourcemanager.ha.id设置
resourcemanager启动报错,其中一个启动成功,另一个启动报8088端口被成功启动的rm占用 2016-11-18 17:08:49,478 INFO org.apache.zookeepe ...
- WPF button 如何区分click和doubleclick
WPF button 同时处理两个事件时候会先触发click事件,触发doubleclick事件 ,那如何区分呢,可以这样设置: private static DispatcherTimer myC ...
- c# js调用AjaxPro方法出错解析
公司的项目的框架中有一部分用到了AjaxPro这个方法,看到这个方法的我一脸懵逼,老老实实去百度了一下. AjaxPro是.NET平台下的一个回调式AJAX框架,使用简单,功能强大.顾名思义ajax, ...
- 6款基于SVG的HTML5CSS3应用和动画
1.CSS3/SVG质感背景小图标 镂空效果图标按钮 今天我们来分享一款用CSS3和SVG实现的质感背景小图标,鼠标滑过图标时出现镂空的效果,并且有质感背景的描边,效果非常不错. 在线演示 源码下载 ...
- 《JavaScript高级程序设计》心得笔记-----第四篇章
第十六章 1. 跨文档消息传送: postMessage("消息", "发送消息的文档所在域") 2. 拖放事件: 1) 拖动某元素会依次触发:drag ...
- JavaScript 弹窗
JavaScript 弹窗 可以在 JavaScript 中创建三种消息框:警告框.确认框.提示框. 警告框 警告框经常用于确保用户可以得到某些信息. 当警告框出现后,用户需要点击确定按钮才能继续进行 ...
- Cstring使用说明
CString::Left(intnCount)const; //从左边1开始获取前 nCount个字符 CString::Mid(intnFirst)const; //从左边第 nCount+1个字 ...
- BMP文件格式分析
前两天要做一个读取bmp文件的小程序,顺便查找了一些关于BMP格式的文章,现在post上来. 简介 BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运 ...
- IOS动画隐式,显式,翻页
// ViewController.m // IOS动画0817 // // Created by 张艳锋 on 15/8/17. // Copyright (c) 2015年 张艳锋. Al ...