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问题