码迷,mamicode.com
首页 > 其他好文 > 详细

lg3708 koishi的数学题 [数学]

时间:2018-02-07 22:53:22      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:scan   tput   output   没有   gpo   例题   fonts   思路   答案   

Description

输入一个整数n,设\(f(x)=\sum_{i=1}^n x~mod~i\),你需要输出 $ f(1),f(2)...f(n)$

Input

一个正整数n。

Output

用空格分隔的n个整数$f(1),f(2)...f(n) $

思路

老师上课讲的例题,方法真的很神奇。

观察样例,然后再继续观察。如果还是没有发现什么的话,就模拟打出一张表好了:(横坐标为x, 纵坐标为y)
技术分享图片
有没有发现什么神奇的地方。显然每一横行加起来就是答案,神奇的是在于纵行!(不要问我怎么发现的)

每一纵行的意义即是,对于一个固定的i, x递增时的\(x ~mod ~ i\)。可以发现它是以i个为循环的数列。

处理上面一个数列复杂度较高,但是我们可以这样处理:发现对于一个固定的i, x递增时的\(x-(x ~mod ~ )i\),它便是每i项增加i的一个数列。于是我们可以每i个数打一个标记,标记意为增加i。

然后我们可以发现,f(x)可以从f(x-1)推到,便是$f(x-1)+n-1-标记。(类似于前缀和+差分维护吧)

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
long long n,j,temp,ans,tag[MAXN]; //tag数组即为标记

int main(){
  scanf("%lld",&n);
  for(int i=2; i<=n; i++)
      for(int j=i; j<=n; j+=i)
          tag[j]+=i;  //处理tag数组,每i位加i
  for(int i=1; i<=n; i++)
  {
      ans+=n-tag[i]-1;
      printf("%lld ",ans); //递推得出答案
  }
  return 0;
}

lg3708 koishi的数学题 [数学]

标签:scan   tput   output   没有   gpo   例题   fonts   思路   答案   

原文地址:https://www.cnblogs.com/CrazyDave/p/8428322.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!