【数学】test20170311

【傻牛的约数研究】(divisor.pas/c/cpp Time:1s Memory:256M)
【问题描述】
  傻牛最近在研究约数,它觉得这玩意很牛逼。首先,对于一个数字 X 来说,设 F(X)表示 X 的约数个数,可以先将 X 表达成 为 若 干 个 质 数 的 幂 次 之 积 , 即 X=p1 k1 *p2 k2 * ... ... *ps ks , 然 后F(X)=(k1+1)*(k2+1)*......*(ks+1)。傻牛觉得这个碉堡了。有一天它想,我们是不是可以求出 F(1)+F(2)+F(3)+......+F(N)的值呢?结果,它晕掉了。
【输入】
  输入文件名为 divisor.in。
  一行一个整数 N,意义见上。
【输出】
  输出文件名为 divisor.out。
  一行一个整数,代表傻牛想求出的值。
【输入输出样例】
  Game.in Game.out
  2    2
  1  2     1
  2  2        

【样例解释】
  F(1)+F(2)+F(3)+F(4)=1+2+2+3=8。
【数据范围】
  对于 50%的数据,保证有 N≤10 3 。
  对于 100%的数据,保证有 N≤10 6 。

【Analysis】

  i:1~n,ans+=n/i(1~n中含因子i的数的个数)

【code】

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 long long n,ans;
 5 int main()
 6 {
 7     freopen("divisor.in","r",stdin);
 8     freopen("divisor.out","w",stdout);
 9     scanf("%lld",&n);
10     for(long long i=1;i<=n;++i)
11         ans+=n/i;
12     printf("%lld\n",ans);
13 }

 

【傻牛的数字游戏】(Game.pas/c/cpp Time:1s Memory:256M)
【问题描述】
  傻牛最近在玩一个数字游戏。首先,规定一个神奇的数字 P,它就是 1000000007。这个游戏是这样的,首先给你一个无比巨大的数字(1000000006!) ^1000000006,当然,这个数字对 P 的模值为 1。然后,游戏可能给你以下两种操作之一,第一种操作就是将这个
数乘以一个数字 X,第二种操作就是将这个数字除以一个数字 X。要求输出每种操作过后这个数字对 P 的模值。现在,傻牛的菊花痒了,要去上厕所了,你不得不帮他玩一盘。
【输入】
  输入文件名 Game.in。
  一行一个数字 N 代表操作总数。
  接下 N 行代表顺次的 N 个操作,每个操作占一行,按“A X”格式给出,A=1 时代表操作 1,A=2 时代表操作 2。
【输出】
  输出文件名 Game.out。
  输出包含 N 行,每行对应这个操作结束时这个数字对 P 的模值。
【输入输出样例】
  Game.in Game.out
  2   2
  1 2  1
  2 2
【数据范围】
  对于 40%的数据,保证有 A=1。
  对于 100%的数据,保证有 N≤10 5 , ,1<=X<=P-1。

【Analysis】

   逆元模板

【code】

  

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int p = 1e9+7;
 7 
 8 typedef long long  ll;
 9 
10 int A, a, b, u, ans;
11 ll x, y, t;
12 
13 void exgcd(int a,int b)
14 {
15     if(!b){x=1;y=0;return;}
16     else
17     {
18         exgcd(b,a%b);
19         t=x;x=y;y=t-a/b*y;
20     }
21 }
22 
23 ll inverse(int a,int m)
24 {
25     exgcd(a,m);
26     return (x%p+p)%p;
27 }
28 
29 int main()
30 {
31     freopen("game.in","r",stdin);
32     freopen("game.out","w",stdout);
33     scanf("%d",&A);
34     ans=1;
35     while(A--)
36     {
37         scanf("%d%d",&a,&u);
38         if(a==1)ans=(1ll*ans*u)%p;
39         else ans=(1ll*ans*inverse(u,p))%p;
40         printf("%d\n",ans);
41     }
42     return 0;
43 }

 

【傻牛的递推数列】(sequence.pas/c/cpp Time:1s Memory:256M)
【问题描述】
  傻牛最近钻研各类数学递推数列。尤其是斐波那契数列。傻牛眼中的斐波那契数列是这样的,F1=1,F2=1,然后 Fi+2=Fi+1 + Fi,逐项递推。今天,傻牛发现,某些斐波那契项之间是成倍数关系的。例如第 4 项 F4=3 和第 8 项F8=21。傻牛想知道,对于某一项 Fx,求所有满足 Fi 是 Fx 是 Fi 倍数的 i 的和是多少?
【输入】
  输入文件名 sequence.in。
  输入包含若干组数据,每组数据一行包括一个正整数 X,意义如上。
【输出】
  输出文件名 sequence.out
  输出包含若干行,每行对应每组数据的解。
【输入输出样例】
 Sequence.in   Sequence.out
 4        7
【输入输出解释】
  F1,F2,F4 是 F4 的约数,所以权值为 1+2+4=7。
【数据范围】
  对于 60%的数据,保证有 X≤1000000,数据组数等于 1。
  对于 100%的数据,保证有 X≤1000000,数据组数小于等于 100000。

【Analysis】

  打表||由斐波那契性质得:求n的所有因子和

【code】

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long LL;
 6 const int size=1000000+10;
 7 int x,ind[size][2];
 8 LL u,v,s,ans=1;
 9 void divide(int a)
10 {
11     s=0;ans=1;
12     if(a%2==0)
13     {
14         ind[++s][0]=2;ind[s][1]=0;
15         while(a%2==0)a/=2,ind[s][1]++;
16     }
17     for(int i=3;i*i<=a;i+=2)
18     {
19         if(a%i==0)
20         {
21             ind[++s][0]=i;ind[s][1]=0;
22             while(a%i==0)a/=i,ind[s][1]++;
23         }
24     }
25     if(a>1)ind[++s][0]=a,ind[s][1]=1;
26 }
27 void power(int a,int f,LL &x,LL &res)
28 {
29     if(f==1){x=a;res=a;return;}
30     power(a,f>>1,x,res);
31     if(!(f&1))res=x*res+res,x*=x;
32     else res=res*x*a+res+a*x,x=x*x*a;
33 }
34 void calc()
35 {
36     for(int i=1;i<=s;++i)
37         power(ind[i][0],ind[i][1],u,v),ans*=(v+1);
38     if(x%2)ans+=2;
39     printf("%lld\n",ans);
40 }
41 int main()
42 {
43     freopen("sequence.in","r",stdin);
44     freopen("sequence.out","w",stdout);
45     while(scanf("%d",&x)!=EOF)
46     {
47         divide(x);
48         calc();
49     }
50     return 0;
51 }

 

posted @ 2017-04-08 17:51  Etta19  阅读(244)  评论(0编辑  收藏  举报