jjzjj

c++ - 在无法存储值的情况下计算系列?

coder 2024-02-20 原文

问题陈述[ here ]

Let be S a infinite secuence of integers:

S0 = a; S1 = b;

Si = |Si-2 - Si-1| for all i >= 2.

You have two integers a and b. You must answer some queries about the n-th element in the sequence.(means print the nth number in the sequence i.e S(n) )

( 0 <= a,b <= 10^18),( 1 <= q <= 100000 )


我尝试过的(这会导致运行时错误):
#include <bits/stdc++.h>
using namespace std;

long long int q,a,b,arr[100002];/*Can't declare an array of required size */
 
int main() {
    // your code goes here
    scanf("%lld%lld",&a,&b);
    arr[0]=a,arr[1]=b;
    scanf("%d",&q);
    int p[100002];
    long long int m = -1;//stores max index asked
    for(int i=0;i<q;i++)
    {
        scanf("%lld",&p[i]);
        m = (m>p[i])?m:p[i];
    }
    for(int i=2;i<=m;i++)//calculates series upto that index
    {
        arr[i]=abs(arr[i-1]-arr[i-2]);
    }
    for(int i=0;i<q;i++)
    {
        printf("%lld\n",arr[p[i]]);
    }
    return 0;
} 

Given : qi fits in 64 bit integer. since index can be very large and i cant declare that bit an array, how should i approach this problem(since brute force would give TLE). Thanks!

最佳答案

哈! 有一个不需要(完整)迭代的解决方案:

考虑一些值 SiSj ,其中 i, j > 1 .然后,查看序列的数字是如何构建的(使用绝对值),我们可以得出结论,两个数字都是正数。

那么它们的差值的绝对值保证小于(或等于)两者中较大的一个。

假设它严格小于两者中较大的值,在接下来的两个步骤中,原始值中较大的值将“超出范围”。由此我们可以得出结论,在这种情况下,序列的数量越来越少。

(*) 如果差值等于较大的一个,则另一个数字一定是 0 .在下一步中,可能会发生以下两种情况之一:

a) 较大的超出范围,那么接下来的两个数字是计算出的差值(等于较大的)和 0,这将再次产生较大的值。然后我们的情况与......

b) 零超出范围。然后下一步将计算较大的和计算出的差异(等于较大的)之间的差异,从而得到0 .在下一步中,这将回到原来的 (*) 情况。

结果: L 的重复模式, L , 0 , ...

一些例子:

3, 1, 2, 1, 1, 0, 1, 1, 0, ...
1, 3, 2, 1, 1, 0, 1, 1, 0, ...
3.5, 1, 2.5, 1.5, 1, .5, .5, 0, .5, .5, 0, ...
.1, 1, .9, .1, .8, .7, .1, .6, .5, .1, .4, .3, .1, .2, .1, .1, 0, ...

将其应用于代码:只要一个值是 0 ,不再需要迭代,接下来的两个数字将与前一个相同,然后再次出现0等等:
// A and B could also be negative, that wouldn't change the algorithm,
// but this way the implementation is easier
uint64_t sequence(uint64_t A, uint64_t B, size_t n) {
 if (n == 0) {
  return A;
 }
 uint64_t prev[2] = {A, B};
 for (size_t it = 1u; it < n; ++it) {
  uint64_t next =
    (prev[0] > prev[1]) ?
      (prev[0] - prev[1]) :
      (prev[1] - prev[0]);
  if (next == 0) {
   size_t remaining = n - it - 1;
   if (remaining % 3 == 0) {
    return 0;
   }
   return prev[0]; // same as prev[1]
  }
  prev[0] = prev[1];
  prev[1] = next;
 }
 return prev[1];
}

Live demo here (如果您愿意,可以使用 ab 值)。

如果您对相同的 A 和 B 进行了重复查询,您可以缓存所有值直到 next == 0std::vector ,为您提供真正恒定的以下查询时间。

我也很确定在序列到达 0 之前存在一个模式,但我找不到它。

我只是注意到我错过了它应该是差异的绝对值......

如果它足够快,这是一个迭代版本:
// deciding on a concrete type is hard ...
uint64_t sequence (uint64_t A, uint64_t B, uint64_t n) {
 if (n == 0) {
  return A;
 }
 uint64_t prev[2] = {A, B};
 for (auto it = 1u; it < n; ++it) {
  auto next =
    (prev[0] > prev[1]) ?
      (prev[0] - prev[1]) :
      (prev[1] - prev[0]);
  prev[0] = prev[1];
  prev[1] = next;
 }
 return prev[1];
}

如您所见,您不需要存储所有值,只需要最后两个数字来计算下一个。

如果这还不够快,您可以添加内存:存储 prev 对有序中的值 std::map (将 n 映射到这些对)。然后,您可以从下一个较低的值 n 的条目开始。而不是从一开始。当然,您还需要管理该 map :保持它很小并充满“有用”的值。

这不是编程问题,而是算法问题。让我们看看该序列的第一个数字:
a
b
a-b
b-(a-b) = 2b-a
(a-b)-(b-(a-b)) = 2(a-b)-b = 2a-3b
2b-a-(2a-3b) = 5b-3a
2a-3b-(5b-3a) = 5a-8b
...

只看系数的绝对值表明......
b: 0 1 1 2 3 5 8 ...
a: (1) 0 1 1 2 3 5 ...

...这是关于斐波那契数列的。然后,还有标志,但这很容易:
b: - + - + - ...
a: + - + - + ...

所以你序列中的第 n 个数字应该等于
f(0) = a
f(n) = (-1)^n      * fib(n-1) * a +
       (-1)^(n-1)  * fib(n)   * b

当然现在我们必须计算第 n 个斐波那契数,但幸运的是已经有一个解决方案:
fib(n) = (phi^n - chi^n) / (phi - chi)
   with
  phi = (1 + sqr(5)) / 2
  chi = 1 - phi

所以,把它带到代码中:
unsigned long fib(unsigned n) {
 double const phi = (1 + sqrt(5)) / 2.0;
 double const chi = 1 - phi;
 return (pow(phi, n) - pow(chi, n)) / (phi - chi);
}
long sequence (long A, long B, unsigned n) {
 if(n ==0) {
  return A;
 }
 auto part_a = fib(n-1) * A;
 auto part_b = fib (n) * B;
 return (n % 2 == 0) ? (part_a - part_b) : (part_b - part_a);
}

一些 live demo is here ,但这在接近更大的数字时会出现问题(我怀疑 fib 变得不正确)。

该演示还包含序列的迭代版本,作为控制。如果这对您来说足够快,请改用它。无需存储比最后两个数字更多的任何内容。

为了进一步改进这一点,您可以使用带有孔的查找表来查找斐波那契数列,即记住序列的每十分之一(及其后继)数。

关于c++ - 在无法存储值的情况下计算系列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31663855/

有关c++ - 在无法存储值的情况下计算系列?的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  5. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  6. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  7. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  8. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

  9. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  10. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

随机推荐