STEPS7.2 数论 ( 数论一直很烂啊。。。)
7.2.1 HDU2824 The Euler function
欧拉函数,打表sum[i]表示phi[1]到phi[i]的和,最后输出sum[b]-sum[a-1]
7.2.2 HDU1787 GCD Again
结果是n-euler(n)-1,eular(n)代表小于n的与n互质的数的个数
7.2.3 HDU1757 A Simple Math Problem
If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
构造矩阵,二分幂
#include <cstdio>
#include <string.h>
using namespace std;
int n,m,a[10];
struct jz{
int t[11][11];
jz(int type){
memset(t,0,sizeof t);
if(type==1){
t[1][2]=t[2][3]=t[3][4]=t[4][5]=t[5][6]=1;
t[6][7]=t[7][8]=t[8][9]=t[9][10]=1;
for(int i=1;i<=10;i++)t[10][i]=a[10-i];
}
}
jz mult(jz jj){
jz r(0);
for(int i=1;i<=10;i++){
for(int j=1;j<=10;j++){
for(int k=1;k<=10;k++){
r.t[i][j]=(r.t[i][j]+t[i][k]*jj.t[k][j])%m;
}
}
}
return r;
}
int getr(){
int res=0;
for(int i=1;i<=10;i++){
res=(res+t[10][i]*(i-1))%m;
}
return res;
}
};
jz efjz(int x){
if(x==1)return jz(1);
jz jza=efjz(x/2);
jz r=jza.mult(jza);
if(x%2==1)r=r.mult(jz(1));
return r;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=0;i<10;i++)scanf("%d",&a[i]);
if(n<10)printf("%d\n",n);
else printf("%d\n",efjz(n-9).getr());
}
return 0;
}
7.2.4 HDU3579 Hello Kiki
不互质情况的中国剩余定理,一直没搞懂不互质怎么做,看了很久还是不懂。。贴下别人的代码,以后有时间再看看
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
__int64 x, y, t;
__int64 egcd(__int64 a, __int64 b)
{
if (b==0)
{
x=1;
y=0;
return a;
}
else
{
__int64 e=egcd(b,a % b);
t=x;
x=y;
y=t-a/b*y;
return e;
}
}
__int64 gcd(__int64 x, __int64 y)
{
if (!x || !y)
return x > y ? x : y;
for (__int64 t; t = x % y; x = y, y = t);
return y;
}
__int64 mm[10],rr[10];
int main()
{
//freopen("in.txt", "r", stdin);
__int64 m1,m2,r1,r2,d,c,t;
bool flag;
__int64 n;
__int64 tc,cnt=0;
scanf ("%I64d",&tc);
while (tc--)
{
cnt++;
scanf ("%I64d",&n);
flag=0;
for (__int64 i=0;i<n;i++)
{
scanf ("%I64d",&mm[i]);
}
for (__int64 i=0;i<n;i++)
{
scanf ("%I64d",&rr[i]);
}
m1=mm[0];
r1=rr[0];
for (__int64 i = 0; i < n - 1; i++)
{
m2=mm[i+1];
r2=rr[i+1];
if (flag)
continue;
d = egcd(m1, m2);
c = r2 - r1;
if (c % d)
{
flag = 1;
continue;
}
t=m2/d;
x=(c/d*x%t+t)%t;
r1=m1*x+r1;
m1=m1*m2/d;
}
if (flag)
{
printf ("Case %I64d: -1\n",cnt);
}
else
{
if (r1==0&&n>1)
{
r1=mm[0];
__int64 ans=1;
for (int i=1;i<n;i++)
r1=gcd(mm[i],r1);
for (int i=0;i<n;i++)
{
ans*=mm[i];
}
r1=ans/r1;
}
if (r1==0&&n==1)
r1=mm[0];
printf ("Case %I64d: %I64d\n",cnt,r1);
}
}
return 0;
}
7.2.5 HDU1299 Diophantus of Alexandria
1/x+1/y=1/n
令y=k,有x=n*n/k+n 即求n*n因数的个数
注意,求n的因数即可求得n*n的因数
n=a1^k1*a2^k2...an^kn 因数为(k1+1)(k2+1)..(kn+1)
n*n=a1^2k1....................因数为(2*k1+1)(2*k2+1)..(2*kn+1)
#include <cstdio>
using namespace std;
/* 1/x+1/y=1/n
* x=n*n/k+n 即求n*n因数的个数
* 注意,求n的因数即可求得n*n的因数
* */
int main(){
int cas,n;
scanf("%d",&cas);
for(int ca=1;ca<=cas;ca++){
scanf("%d",&n);
int res=1,tmp;
for(int i=2;i*i<=n;i++){
tmp=1;
while(n%i==0){
n/=i;
tmp++;
}
res*=(tmp*2-1);
}
if(n!=1)res=res*3;
res=(res+1)>>1;
printf("Scenario #%d:\n",ca);
printf("%d\n",res);
printf("\n");
}
return 0;
}
7.2.6 HDU3802 Ipad,IPhone
7.2.7 HDU2815 Mod Tree
7.2.8 HDU1753 X问题