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. merge into sql优化

    今天网友说他的merge into sql跑了15分钟了还没有跑出数据,问我能不能优化一下,我让他把sql和sql的执行计划发过来 merge into F_Sal_P_Camp_Samp_Cust_ ...

  2. the forth assignment of software testing

    软件测试用到的 pict33.msi. 加载安装即可. 顺步安装 使用背景: 假如现在有一个网站后台需要测试工程师进行测试用例设计.用常规的方法将参数列出: 帐户名: 空,不存在,超长,超短,正常 密 ...

  3. 深入理解计算机系统第二版习题解答CSAPP 2.1

    A.将0x39A7F8转换为二进制. 0011 1001  1010 0111  1111 1000 B.将二进制1100 1001 0111 1011转换为十六进制. 0xC97B C.将0xD5E ...

  4. ERROR 1114 (HY000): The table 'adv_date_tmp' is full(Mysql临时表应用)

    场景:需要对现在数据库的数据进行批量的进行is_del=1的操作,但是遇到一个问题,在执行sql的时候发现sql不能在查询特定表的时候再嵌套查询来做update的操作,经过讨论,后续我们想到用临时表的 ...

  5. windows下使用redis,Redis入门使用,Redis基础命令

    windows下使用redis,Redis入门使用,Redis基础命令 >>>>>>>>>>>>>>>> ...

  6. webrtc学习——RTCPeerConnection

    The RTCPeerConnection interface represents a WebRTC connection and handles efficient streaming of da ...

  7. c语言学习之基础知识点介绍(十五):函数的指针

    一.函数的指针的介绍 /* 函数指针: 函数的指针,本质上一个指针 指向函数的指针,就是一个函数指针. 回忆:我们写的源代码编译成二进制的指令集,一串交给CPU执行的指令 先存在内存里面,然后CPU读 ...

  8. c语言学习之基础知识点介绍(十四):指针的进阶

    一.指针的加.减法运算 /* 1.加法运算 1).可以跟整数进行加法运算,得到的还是一个地址 公式: 地址 + 1 = 地址 + 1 * 类型所占的字节数 地址 + n = 地址 + n * 类型所占 ...

  9. Android colors.xml

    <?xml version="1.0" encoding="utf-8"?><resources> <color name=&qu ...

  10. 学习笔记_JDBC_1_Demo1_连接数据库的基本操作和步骤

    常见错误:连数据库时,这句话String url = "jdbc:mysql://localhost/数据库名";数据库名可能和你建的数据库名不一样 1.安装Mysql,记住此时你 ...