problem 1006 (hdu 4671)
Backup Plan
思路:水题,,直接找规律就好了,,
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<stack> 7 8 using namespace std; 9 const int maxn=105; 10 int map[maxn][maxn]; 11 int head[maxn]; 12 int main() 13 { 14 int n,m; 15 while(scanf("%d%d",&n,&m)!=EOF) 16 { 17 int i,j; 18 for(i=1; i<=m; i++) 19 { 20 map[i][1]=i%n; 21 if(i%n==0) 22 map[i][1]=n; 23 head[i]=map[i][1]; 24 } 25 int u=n; 26 for(i=1; i<=m;) 27 { 28 map[i][2]=u; 29 int s=3; 30 if(map[i][1]<map[i][2]) 31 { 32 for(j=1; j<head[i]; j++) 33 { 34 map[i][s]=j; 35 s++; 36 } 37 for(j++; j<u; j++) 38 { 39 map[i][s]=j; 40 s++; 41 } 42 for(j++; j<=n; j++) 43 { 44 map[i][s]=j; 45 s++; 46 } 47 } 48 else 49 { 50 for(j=1; j<u; j++) 51 { 52 map[i][s]=j; 53 s++; 54 } 55 for(j++; j<head[i]; j++) 56 { 57 map[i][s]=j; 58 s++; 59 } 60 for(j++; j<=n; j++) 61 { 62 map[i][s]=j; 63 s++; 64 } 65 } 66 i++; 67 if(i%n==u%n) 68 { 69 u--; 70 } 71 if(u==0) 72 u=n; 73 //printf("u=%d ",u); 74 } 75 for(i=1; i<=m; i++) 76 { 77 for(j=1; j<n; j++) 78 { 79 printf("%d ",map[i][j]); 80 } 81 printf("%d ",map[i][j]); 82 } 83 } 84 return 0; 85 }
problem 1010 (hdu 4675)
GCD of Sequence
思路:组合数的题
枚举d的值,,,a[]中有x个d的倍数,那么从x中选出(n-k)个位置,且每个位置的值是m/d-1种,剩下的(n-x)个位置,则可以随便取值,只要是d的倍数即可,所以有(m/d)种
所以得出公式 res= c(n-k,x)*(m/d-1)^(x-(n-k))*(m/d)^(n-x);这个公式得出的是以d为公约数的种类数,但是不是以d为最大公约数的种数,所以需要去重,即从m循环到1,,一次减去是d的倍数的种类数,,,即f[d]=res-f[2*d]-f[3*d]......
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<queue> 7 #include<ctime> 8 #include<stack> 9 #include<vector> 10 #include<cmath> 11 #define LL __int64 12 using namespace std; 13 const int maxn=300010; 14 const int mod=1000000007; 15 int a[maxn]; 16 LL g[maxn]; 17 LL f[maxn]; 18 int num[maxn]; 19 int prim[maxn]; 20 bool vis[maxn]; 21 LL C[maxn]; 22 int cnt=0; 23 LL inv(LL x)//求幺元,用pow(x,mod-2)的方法会超时 24 { 25 if(x==1) 26 return x; 27 return (inv(mod%x)*(mod-mod/x)%mod)%mod; 28 } 29 LL poow(LL p,LL n)//传参用LL 30 { 31 LL sp=1; 32 while(n>0) 33 { 34 if(n%2==1) 35 sp=sp*p%mod; 36 n/=2; 37 p=p*p%mod; 38 39 } 40 return sp%mod; 41 } 42 int main() 43 { 44 int n,m,k; 45 while(scanf("%d%d%d",&n,&m,&k)!=EOF) 46 { 47 int i,j; 48 memset(num,0,sizeof(num)); 49 for(i=1; i<=n; i++) 50 { 51 scanf("%d",&a[i]); 52 num[a[i]]++; 53 } 54 C[n-k]=1; 55 for(i=n-k+1; i<=n; i++) 56 { 57 C[i]=(((C[i-1]*i)%mod)*inv(i-(n-k)))%mod; 58 C[i]%=mod; 59 } 60 for(i=m; i>=1; i--) 61 { 62 LL x=0; 63 LL cnt=0; 64 for(j=1;j<=m;j++) 65 { 66 if(i*j>m) 67 break; 68 x+=num[i*j]; 69 if(j>1) 70 { 71 cnt+=f[i*j]%mod; 72 cnt%=mod; 73 } 74 75 } 76 if(n-k>x)//不满足题目中有k个不同,即有n-k个相同 77 { 78 f[i]=0; 79 continue; 80 } 81 if(m/i==1)//此时的幂的计算底为0,注意 82 { 83 if(n-k==x) 84 f[i]=1; 85 else 86 f[i]=0; 87 continue; 88 } 89 90 f[i]=(((C[x]*poow((m/i)-1,x-(n-k)))%mod)*(poow(m/i,n-x)%mod))%mod; 91 f[i]=(f[i]-cnt+mod)%mod;//f[i]可能为负 92 } 93 for(i=1;i<m;i++) 94 { 95 printf("%I64d ",f[i]); 96 } 97 printf("%I64d ",f[m]); 98 99 } 100 return 0; 101 }