2013 Multi-University Training Contest 7 部分解题报告

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 }
View Code

 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 }
View Code
原文地址:https://www.cnblogs.com/wanglin2011/p/3267323.html