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

数论专题hdu2197

时间:2017-09-16 22:06:50      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:ima   技巧   nbsp   sum   分享   mes   div   pre   ace   

  技术分享

    本题题意:求长度为n的本元串的个数,本元串就是无法由几个相同的子串拼接的01串。

    代码如下:

    

#include <iostream>
using namespace std;
typedef long long ll;
const int mod = 2008;
ll pow_(ll a,ll b,ll mod){

    ll sum = 1;

    while(b){
        
        if(b&1){
    
            sum = sum * a % mod;

        }

        a = a * a % mod;
    
        b >>= 1;

    }

    return sum;

}
ll cal(ll n){

    ll sum = 0;

    for(int i=2;i*i<=n;i++){

        if(n % i == 0){
        
            sum = (sum + cal(i)) % mod;

            if(i*i!=n){

                sum = (cal(n/i) + sum) % mod;

            }    

        }

    }

    return (pow_(2,n,mod) - sum - 2 + 2008) % mod;

}

int main(){

    ll n;

    while(cin >> n){

        if(n == 1){

            cout << 2 << endl;

        }else{

            cout << cal(n) << endl;

        }

    }

    return 0;


}

 

这道题第一眼看到的感觉就是打表,然而发现10e8太大,打了很久也没打出来,后来就只能直接去求了,好在一看,直接求的复杂度也不是特别高,然后就写了个递归,过了(第一发wa发现是没有特判n=1)。

这节学了个很不错的技巧,可以用i*i代替sqrt(n),还有注意如果测试发现500爆0,只是因为刚好mod了,你并没有错。。

 

数论专题hdu2197

标签:ima   技巧   nbsp   sum   分享   mes   div   pre   ace   

原文地址:http://www.cnblogs.com/mtl6906/p/7532871.html

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