【数学】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 }