2401: 陶陶的难题I

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 89  Solved: 24
[Submit][Status]

Description

最近陶陶在研究数论,某天他偶然遇到一道题:对于给定的正整数���,求出
下面这样一个式子的值:

其中LCM(a���, b���)表示正整数���和���最小公倍数,即能同时被a���和b���整除的最小正
整数。
作为神犇的陶陶,当然轻松秒杀了这道题。不过他希望你写一个程序,用来
检验他算的答案是否正确。

Input

第一行包含一个正整数���T,表示有T���组测试数据。接下来���T<=10^5
行,每行给出一个正整数N,N<=10^6。

Output

包含T���行,依次给出对应的答案。

Sample Input

7
1
10
100
1000
10000
100000
1000000

Sample Output

1
2127
18446224
183011304660
1827127167830060
18269345553999897648
182690854273058293758232

   最开始试图通过一种很逗逼的做法弄这道题,其实也A的程序复杂度完全相同,都是一个调和计数的O(nlogn),但是由于我最开始的方法for语句内高精度加要多算那么一两次,所以就稳稳地被卡常数了,而且这个常数致使我删掉了300+的高精度模板,改用一个pair表示int128。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
#define MAXN 1000001
typedef long long qword;
int prime[MAXN+],topp=-;
bool pflag[MAXN+];
int phi[MAXN+];
qword maxval=100000000000000000LL;
struct mypair
{
qword first,second;
mypair(qword x,qword y):first(x),second(y){};
mypair(){};
inline void operator += (mypair& pp)
{
first+=pp.first;
second+=pp.second;
if (second>=maxval)
{
first++;
second-=maxval;
}
}
inline void operator -=(mypair& pp)
{
first-=pp.first;
second-=pp.second;
if (second<)
{
second+=maxval;
first--;
}
}
};
mypair res[MAXN+];
void init()
{
register int i,j;
phi[]=;
for (i=;i<MAXN;i++)
{
if (!pflag[i])
{
prime[++topp]=i;
phi[i]=i-;
}
for (j=;j<=topp && i*prime[j]<MAXN;j++)
{
pflag[i*prime[j]]=true;
if (i%prime[j]==)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*(prime[j]-);
}
}
register mypair g,gt,g0;
g.first=g.second=;;
for (i=;i<MAXN;i++)res[i].first=,res[i].second=;
for (i=;i<MAXN;i++)
{
g.first+=(qword)i*i*phi[i]/maxval;
g.second+=(qword)i*i*phi[i]%maxval;
if (g.second>=maxval)
{
g.first+=g.second/maxval;
g.second%=maxval;
}
gt.first=gt.second=;g0=g;
for (j=;i*j<MAXN;j++)
{
gt+=g0;
res[i*j]+=gt;
if (i*j+j<MAXN)
{
res[(i+)*j]-=gt;
}
}
}
//for (i=1;i<MAXN;i++)res[i].first-=100000;
for (i=;i<MAXN;i++)
res[i]+=res[i-];
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("b.txt","w",stdout);
init();
qword i,j,k,x,y,z,n,m;
qword nn;
scanf("%lld",&nn);
qword ans=;
while (nn--)
{
scanf("%lld",&n);
if (res[n].first)
printf("%lld%017lld\n",res[n].first,res[n].second);
else
printf("%lld\n",res[n].second);
}
}

TLE

  换了一种方法,联想lcmsum的做法,通过与n互质数的和为n*phi[n]/2这个公式可以很轻松推出正解,但是还是非常慢,至少还是可以A掉吧。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
#define MAXN 1000001
typedef unsigned long long qword;
int prime[MAXN+],topp=-;
bool pflag[MAXN+];
int phi[MAXN+];
qword maxval=100000000000000000LLU;
struct mypair
{
qword first,second;
mypair(qword x,qword y):first(x),second(y){};
mypair(){};
inline void operator += (mypair& pp)
{
first+=pp.first;
second+=pp.second;
if (second>=maxval)
{
first++;
second-=maxval;
}
}
inline void operator -=(mypair& pp)
{
first-=pp.first;
second-=pp.second;
if (second<)
{
second+=maxval;
first--;
}
}
};
mypair res[MAXN+];
void init()
{
register int i,j;
phi[]=;
for (i=;i<MAXN;i++)
{
if (!pflag[i])
{
prime[++topp]=i;
phi[i]=i-;
}
for (j=;j<=topp && i*prime[j]<MAXN;j++)
{
pflag[i*prime[j]]=true;
if (i%prime[j]==)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*(prime[j]-);
}
}
for (i=;i<MAXN;i++)
{
register qword x=(qword)phi[i]*i/;
if (i==)x=;
for (j=i;j<MAXN;j+=i)
{
res[j].second+=x*j;
if (res[j].second>=maxval)
{
res[j].first+=res[j].second/maxval;
res[j].second%=maxval;
}
}
}
for (i=;i<MAXN;i++)
{
res[i].first*=,res[i].second*=;
res[i].second-=i;
if (res[i].second>=maxval)
{
res[i].second-=maxval;
res[i].first++;
}
if (res[i].second<)
{
res[i].second+=maxval;
res[i].first--;
}
res[i]+=res[i-];
}
return ;
/*
register mypair g,gt,g0;
g.first=g.second=0;;
for (i=1;i<MAXN;i++)res[i].first=0,res[i].second=0;
for (i=1;i<MAXN;i++)
{
g.second+=(qword)i*i*phi[i];
if (g.second>=maxval)
{
g.first+=g.second/maxval;
g.second%=maxval;
}
gt.first=gt.second=0;g0=g;
for (j=1;i*j<MAXN;j++)
{
gt+=g0;
res[i*j]+=gt;
if (i*j+j<MAXN)
{
res[(i+1)*j]-=gt;
}
}
}
for (i=2;i<MAXN;i++)
res[i]+=res[i-1];*/
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("b.txt","w",stdout);
init();
qword i,j,k,x,y,z,n,m;
qword nn;
scanf("%lld",&nn);
qword ans=;
while (nn--)
{
scanf("%lld",&n);
if (res[n].first)
printf("%llu%017llu\n",res[n].first,res[n].second);
else
printf("%llu\n",res[n].second);
}
}

bzoj 2401: 陶陶的难题I 数论的更多相关文章

  1. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  2. bzoj 2402: 陶陶的难题II 二分答案维护凸包

    2402: 陶陶的难题II Time Limit: 40 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 68  Solved: 45[Submi ...

  3. [BZOJ2402]陶陶的难题II(树链剖分+线段树维护凸包+分数规划)

    陶陶的难题II 时间限制:40s      空间限制:128MB 题目描述 输入格式 第一行包含一个正整数N,表示树中结点的个数. 第二行包含N个正实数,第i个数表示xi (1<=xi<= ...

  4. 【BZOJ2401】陶陶的难题I 欧拉函数+线性筛

    [BZOJ2401]陶陶的难题I 题意:求,n<=1000000,T<=100000 题解:直接做是n*sqrt(n)的,显然会TLE,不过这题a和b都是循环到n,那么就可以进行如下的神奇 ...

  5. P1676陶陶吃苹果 - vijos

    描述 curimit知道陶陶很喜欢吃苹果.于是curimit准备在陶陶生日的时候送给他一棵苹果树. curimit准备了一棵这样的苹果树作为生日礼物:这棵苹果树有n个节点,每个节点上有c[i]个苹果, ...

  6. 武汉科技大学ACM:1007: 陶陶摘苹果

    Problem Description 厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试. 个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹 ...

  7. 洛谷-陶陶摘苹果(升级版)-BOSS战-入门综合练习1

    题目描述 Description 又是一年秋季时,陶陶家的苹果树结了n个果子.陶陶又跑去摘苹果,这次她有一个a公分的椅子.当他手够不着时,他会站到椅子上再试试. 这次与NOIp2005普及组第一题不同 ...

  8. NOIP2005-普及组复赛-第一题-陶陶摘苹果

    题目描述 Description 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳 ...

  9. noip普及组2005 陶陶摘苹果

    陶陶摘苹果 描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试. 现在 ...

随机推荐

  1. quartz多个scheduler实现

    1.首先排除错误用法 SchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = sche ...

  2. Linux 下mysql忘记root密码解决方法

    忘记root密码怎么办:1.关闭数据库2.使用-->mysqld_safe --skip-grant-tables &--<启动数据库3.使用空密码进入数据库(mysql命令后直接 ...

  3. Leetcode Python Solution(continue update)

    leetcode python solution 1. two sum (easy) Given an array of integers, return indices of the two num ...

  4. 百度编辑器umeditor使用总结

    百度编辑器是一个功能很全.很强大. 百度单张图片上传只能存储在项目下面,而不能独立自定义存储位置,因此重写上传代码 百度文章中的图片是通过base64实现的,直接存储在数据库中 tomcat通过虚拟路 ...

  5. flash&nbsp;wmode=&quot;window&amp;qu…

    引用一段话:opaque和tranparent由于都是无窗口内渲染模式,能很好的实现各层的遮挡,和一般div元素没有太大区别,而window.direct模式在现在看来,是没有任何办法实现被DHTML ...

  6. 纯js写图片轮播插件

    最近终于写成了自己创作的图片轮播插件,使用原生js编写.与目前网上流行的轮播插件相比,功能和效果稍弱,但是使用起来相当方便. 先看html代码 <!DOCTYPE html> <ht ...

  7. 周末充电之WPF(四).多窗口之间操作

    多窗口实例: 1.在多个窗口的情况下如何自定义指定要启动的窗口程序 <Application x:Class="toolbar.App" xmlns="http:/ ...

  8. oracle 11g 64位安装sqldeveloper打开不了

    oracle 11g 64位安装sqldeveloper打开不了解决方法: 1.到官网下载对应版本的sqldeveloper. 2.找对应安装路径下的F:\app\Administrator\prod ...

  9. 注册一个比较大小Handlebars

    1.显示的数据 var datas = { id:"number" } 2.temp模板 <script id="template" type=" ...

  10. [转]CSS 模块

    CSS 模块 如果你想知道 CSS 最近发展的转折点,你应该选择去观看 Christopher Chedeau 在2014年11月的 NationJS 大会上做的名称为 CSS in JS 的分享.不 ...