INOI 2015 - 周期性弦乐

时间:2017-12-24 17:35:35

标签: c++ algorithm

问题:https://www.codechef.com/INOIPRAC/problems/INOI1502

这是我想到的 -

  • 有一个函数f(n),它找到n

  • 的因子
  • 如果找到因子i,请调用f(i)

  • 对于n的每个值,该函数还计算非周期性字符串的数量将等于2 ^ n - (每个函数调用返回的值)

  • 返回非周期性字符串的数量并将此数字存储在数组中以防止

然后我只调用函数f(n)modulo n得到输出

它适用于较小的值,但不适用于较大的值

例如,当n = 35&米= 99999989

截至目前我的代码:

#include <iostream>
#include <cmath>
using namespace std;
int arr[150100];
int ans[150100];
int check(int n){
    if(arr[n]>0){
        return arr[n];
    }
    else if(n == 1){
        arr[n] = 2;
        return 2;
    }
   if(n==2){
       arr[n] = 2;
       return 2;
    }
    for(int i =1 ;i<(n/2) +1;i++){

        if(n%i == 0){
            ans[n] -= check(i);//2+
        }
    }

    arr[n] = ans[n];
    return ans[n];
}
int main() {
    int n,m;
    cin>>n>>m;
    for(int i=0;i<=150100;i++){
        arr[i] = 0;
        ans[i] = pow (2,i);
    }
    std::cout<<( check(n) )%m<<endl;
}

完整的问题陈述:

  

字符串是01 s的任何非空序列。字符串的示例包括001011110001001。字符串的长度是其中的符号数。例如,111000的长度为6.如果 u v 是字符串,则 uv 是通过连接获得的字符串 u v 。例如,如果 = 110 v = 0010 uv = 1100010

     

如果存在字符串 v w = v,则字符串 w 周期性 n = vv···v n 次),对于某些 n ≥2。请注意,在这种情况下, v 的长度严格小于 w 的长度。例如,110110是定期的,因为 v = 110 vv

     

给定正整数N,找到长度为N且不是周期性的字符串数。以模M的形式报告答案。长度为2的非周期性字符串为1001。长度为3的非周期性字符串为001010011100101110

     

输入格式

     

一行,包含两个以空格分隔的整数NM

1 个答案:

答案 0 :(得分:0)

好的,我会从你选择的内置类型开始,它不是你的例子的最佳选择:n = 35&amp; M = 99999989。通常int的大小是32位,因此它能够保持最大2 ^ 32。因此,对于您的示例,您应该选择能够保持最少35位的类型。

long long也不是很好的选择,因为你使用的modulo函数适用于整数,如果你想在大于int的类型上应用modulo,你会更喜欢使用函数fmod,请参阅http://www.cplusplus.com/reference/cmath/fmod/

在你的实现中我更喜欢使用double类型,在大多数系统上它的大小是64位,下面是带有一些更正的代码:

User::mailitem_id

请注意,此修复程序仅适用于N到64,因为在大多数系统中,双倍大小为64位。

您应该考虑的第二个问题是您的“ans”数组,您尝试使用比int大得多或者能够容纳双倍的值来初始化它,大于2 ^ 64的值。在这种情况下,“ans”中会有截断的数据。

对于这个任务,我更喜欢另一种方法,包括模幂运算规则:ab mod m =(a mod m)(b mod m)mod m =(a(b mod m))mod m

根据问题2中的描述≤M≤10^ 8,因此在此任务中保持整数数组就足够了。 例如,要计算2 ^ 150000 mod 10 ^ 8,而不是直接评估2 ^ 150000,请逐步执行并在每一步采用模数。