Description

F(n) = (n % 1) + (n % 2) + (n % 3) + ...... (n % n)。其中%表示Mod,也就是余数。
例如F(6) = 6 % 1 + 6 % 2 + 6 % 3 + 6 % 4 + 6 % 5 + 6 % 6 = 0 + 0 + 0 + 2 + 1 + 0 = 3。
给出n,计算F(n)。

Input

输入1个数N(2 <= N <= 10^12)。

Output

输出F(n)。

Sample Input

6

Sample Output

3
 
这是51NOD上的一道题,由于提交不了,所以搞到我们学校的OJ提交了。
这个题目n达10^12这么大,自然不可能走一遍。
然后由于n%i = n-[n/i]*i
所以sum(n%i) = sum(n-[n/i]*i) = n*n - sum([n/i]*i)。
考虑到取整那部分,当i在连续的一段区间内可能值会不变。
=>[n/i] = [n/j] => j = n/(n/i)这里的除法为取下整。
于是便可以考虑分组运算了。
 
当然可以将i和n/i两组再次合并,这样理论上能减少一倍的时间。
 
由于数据很大,用了C++高精度。
 
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long using namespace std; const int UNIT = ;
struct Bignum
{
int val[];
int len; Bignum()
{
memset(val, , sizeof(val));
len = ;
} Bignum operator=(const LL &a)
{
LL t, p = a;
len = ;
while (p >= UNIT)
{
t = p - (p/UNIT)*UNIT;
p = p / UNIT;
val[len++] = t;
}
val[len++] = p;
return *this;
} Bignum operator+(const Bignum &a) const
{
Bignum x = a;
int L;
L = a.len > len ? a.len : len;
for (int i = ; i < L; ++i)
{
x.val[i] += val[i];
if (x.val[i] >= UNIT)
{
x.val[i+]++;
x.val[i] -= UNIT;
}
}
if (x.val[L] != )
x.len = L+;
else
x.len = L;
return x;
} Bignum operator-(const Bignum &a) const
{
bool flag;
Bignum x1, x2;
if (*this > a)
{
x1 = *this;
x2 = a;
flag = ;
}
else
{
x1 = a;
x2 = *this;
flag = ;
}
int j, L = x1.len;
for (int i = ; i < L; ++i)
{
if (x1.val[i] < x2.val[i])
{
j = i+;
while (x1.val[j] == )
j++;
x1.val[j--]--;
while (j > i)
x1.val[j--] += UNIT-;
x1.val[i] += UNIT-x2.val[i];
}
else
x1.val[i] -= x2.val[i];
}
while (x1.val[x1.len-] == && x1.len > )
x1.len--;
if (flag)
x1.val[x1.len-] = -x1.val[x1.len-];
return x1;
} Bignum operator*(const Bignum &a) const
{
Bignum x;
int i, j, up;
int x1, x2;
for (i = ; i < len; i++)
{
up = ;
for (j = ; j < a.len; j++)
{
x1 = val[i]*a.val[j] + x.val[i+j] + up;
if (x1 >= UNIT)
{
x2 = x1 - x1/UNIT*UNIT;
up = x1 / UNIT;
x.val[i+j] = x2;
}
else
{
up = ;
x.val[i+j] = x1;
}
}
if (up != )
x.val[i+j] = up;
}
x.len = i + j;
while (x.val[x.len-] == && x.len > )
x.len--;
return x;
} Bignum operator/(const int &a) const
{
Bignum x;
int down = ;
for (int i = len-; i >= ; --i)
{
x.val[i] = (val[i]+down*UNIT) / a;
down = val[i] + down*UNIT - x.val[i]*a;
}
x.len = len;
while (x.val[x.len-] == && x.len > )
x.len--;
return x;
} LL operator%(const LL &a) const
{
LL x = ;
for (int i = len-; i >= ; --i)
x = ((x*UNIT)%a+val[i]) % a;
return x;
} bool operator>(const Bignum &a) const
{
int now;
if (len > a.len)
return true;
else if (len == a.len)
{
now = len - ;
while (val[now] == a.val[now] && now >= )
now--;
if(now >= && val[now] > a.val[now])
return true;
else
return false;
}
else
return false;
}
}ans, tmp, ttmp; LL n; void work()
{
ans = n;
ans = ans*ans;
LL j;
for (LL i = ; i <= n; i++)
{
j = n/(n/i);
tmp = i+j;
ttmp = j-i+;
tmp = tmp*ttmp;
tmp = tmp/;
ttmp = n/i;
tmp = tmp*ttmp;
ans = ans-tmp;
i = j;
}
} void output()
{
for (int i = ans.len-; i >= ; --i)
printf("%d", ans.val[i]);
printf("\n");
} int main()
{
//freopen("test.in", "r", stdin);
while (scanf("%lld", &n) != EOF)
{
work();
output();
}
return ;
}

ACM学习历程—SNNUOJ1132 余数之和(数论)的更多相关文章

  1. ACM学习历程—HDU5668 Circle(数论)

    http://acm.hdu.edu.cn/showproblem.php?pid=5668 这题的话,假设每次报x个,那么可以模拟一遍, 假设第i个出局的是a[i],那么从第i-1个出局的人后,重新 ...

  2. ACM学习历程—HDU5667 Sequence(数论 && 矩阵乘法 && 快速幂)

    http://acm.hdu.edu.cn/showproblem.php?pid=5667 这题的关键是处理指数,因为最后结果是a^t这种的,主要是如何计算t. 发现t是一个递推式,t(n) = c ...

  3. ACM学习历程—HDU5666 Segment(数论)

    http://acm.hdu.edu.cn/showproblem.php?pid=5666 这题的关键是q为质数,不妨设线段上点(x0, y0),则x0+y0=q. 那么直线方程则为y = y0/x ...

  4. ACM学习历程—HDU5585 Numbers(数论 || 大数)(BestCoder Round #64 (div.2) 1001)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5585 题目大意就是求大数是否能被2,3,5整除. 我直接上了Java大数,不过可以对末尾来判断2和5, ...

  5. ACM学习历程—HDU5637 Transform(数论 && 最短路)

    题目链接:http://codeforces.com/problemset/problem/590/A 题目大意是给两种操作,然后给你一个s,一个t,求s至少需要多少次操作到t. 考虑到第一种操作是将 ...

  6. ACM学习历程—HDU1719 Friend(数论)

    Description Friend number are defined recursively as follows. (1) numbers 1 and 2 are friend number; ...

  7. 51nod 1225 余数之和 数论

    1225 余数之和 题目连接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1225 Description F(n) ...

  8. ACM学习历程—ZOJ3785 What day is that day?(数论)

    Description It's Saturday today, what day is it after 11 + 22 + 33 + ... + NN days? Input There are ...

  9. ACM学习历程—SNNUOJ 1239 Counting Star Time(树状数组 && 动态规划 && 数论)

    http://219.244.176.199/JudgeOnline/problem.php?id=1239 这是这次陕西省赛的G题,题目大意是一个n*n的点阵,点坐标从(1, 1)到(n, n),每 ...

随机推荐

  1. Windows系统SVN服务器搭建与使用

    下载svn:https://tortoisesvn.net/downloads.zh.html下载svn服务器:https://www.visualsvn.com/server/download/(如 ...

  2. ASIHTTP

    本文转载至 http://www.th7.cn/Program/IOS/201303/128223.shtml     向服务器端上传数据 ASIFormDataRequest ,模拟 Form表单提 ...

  3. TP框架的增删改

    TP添加数据有三种方式 1. //1.使用数组添加 $n = M("nation"); $arr = array("Code"=>"n007&q ...

  4. 一些blog地址总结整理:

    女神 python之路-网络编程初版:https://www.cnblogs.com/Eva-J/articles/8066842.html python之路-网络编程(重点看这个,更细致):http ...

  5. 去掉标题栏/ActionBar后点击menu键时应用崩溃

    MainActivity 继承了 ActionBarActivity后,想要去掉标题栏(ActionBar),在程序中加上requestWindowFeature(Window.FEATURE_NO_ ...

  6. JavaWeb:前端开发基础

    JavaWeb:前端开发基础 内联元素和块级元素 说明: 联元素和块级元素都是html中的范畴,块元素和内联元素的主要差异是块元素是从新的一行开始.而内联元素一般显示在一行上.但是可以通过css的di ...

  7. 每天一个Linux命令(19)find命令_初识

    Linux下find命令在目录结构中搜索文件,并执行指定的操作.     (1)用法: 用法: find pathname    -option      [-print | -exec | -ok] ...

  8. Effective java -- 7 通用程序设计

    第四十五条:将局部变量的作用域最小化 第四十六条:加强版for循环优于传统for循环 第四十七条:了解和使用类库书中提到了一个生成随机数的例子.正好需要. public static void mai ...

  9. Data Structure Array: Find the minimum distance between two numbers

    http://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/ #include <iostream> ...

  10. python内置方法补充any

    any(iterable) 版本:该函数适用于2.5以上版本,兼容python3版本. 说明:如果iterable的任何元素不为0.''.False,all(iterable)返回True.如果ite ...