zoukankan      html  css  js  c++  java
  • HDU-4675 GCD of Sequence 数学

      题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4675

      题意:给一个大小为N的数列a[i],然后一个数M以及一个数K,要你求得一个数列b[i],其中b[i]有K个数与a[i]中的不相同,使得gcd(b[i])=j。对于每个 j ,求出满足的b[i]的个数。。

      首先我们统计数列a[i]每个数的个数,假设现在求gcd(b[i])=j,那么可以在t=M/j的时间内求出 j 的倍数的个数cnt。那么就相当于在cnt个中选择N-K个不变C(cnt,N-K),在剩下的 j 的倍数中有(t-1)^(cnt-t)种,非 j 的倍数中有t^(N-cnt)种,那么就是C(cnt,N-K)*(t-1)^(cnt-t)*t^(N-cnt)。这里求出的是gcd(b[i])为 j 的倍数的情况,还要减去2*j,3*j...的数目,因此 j 从M开始倒推就可以了,减去ans[2*j],ans[3*j]...

      1 //STATUS:C++_AC_1796MS_6144KB
      2 #include <functional>
      3 #include <algorithm>
      4 #include <iostream>
      5 //#include <ext/rope>
      6 #include <fstream>
      7 #include <sstream>
      8 #include <iomanip>
      9 #include <numeric>
     10 #include <cstring>
     11 #include <cassert>
     12 #include <cstdio>
     13 #include <string>
     14 #include <vector>
     15 #include <bitset>
     16 #include <queue>
     17 #include <stack>
     18 #include <cmath>
     19 #include <ctime>
     20 #include <list>
     21 #include <set>
     22 #include <map>
     23 using namespace std;
     24 //#pragma comment(linker,"/STACK:102400000,102400000")
     25 //using namespace __gnu_cxx;
     26 //define
     27 #define pii pair<int,int>
     28 #define mem(a,b) memset(a,b,sizeof(a))
     29 #define lson l,mid,rt<<1
     30 #define rson mid+1,r,rt<<1|1
     31 #define PI acos(-1.0)
     32 //typedef
     33 typedef __int64 LL;
     34 typedef unsigned __int64 ULL;
     35 //const
     36 const int N=300010;
     37 const int INF=0x3f3f3f3f;
     38 const LL MOD=1000000007,STA=8000010;
     39 const LL LNF=1LL<<55;
     40 const double EPS=1e-9;
     41 const double OO=1e50;
     42 const int dx[4]={-1,0,1,0};
     43 const int dy[4]={0,1,0,-1};
     44 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
     45 //Daily Use ...
     46 inline int sign(double x){return (x>EPS)-(x<-EPS);}
     47 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
     48 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
     49 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
     50 template<class T> inline T Min(T a,T b){return a<b?a:b;}
     51 template<class T> inline T Max(T a,T b){return a>b?a:b;}
     52 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
     53 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
     54 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
     55 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
     56 //End
     57 
     58 LL C[N],ans[N];
     59 int cnt[N];
     60 int n,m,k;
     61 
     62 void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
     63 {
     64     if(!b){d=a;x=1;y=0;}
     65     else {exgcd(b,a%b,d,y,x);y-=x*(a/b);}
     66 }
     67 
     68 LL inv(LL a)
     69 {
     70     LL d,x,y;
     71     exgcd(a,MOD,d,x,y);
     72     return (x+MOD)%MOD;
     73 }
     74 
     75 LL mulpow(LL n,int m)
     76 {
     77     LL ret=1;
     78     for(;m;m>>=1){
     79         if(m&1)ret=(ret*n)%MOD;
     80         n=(n*n)%MOD;
     81     }
     82     return ret;
     83 }
     84 
     85 int main(){
     86  //   freopen("in.txt","r",stdin);
     87     int i,j,a,tot,t,p;
     88     LL s;
     89     while(~scanf("%d%d%d",&n,&m,&k))
     90     {
     91         C[t=n-k]=1;
     92         for(i=t+1;i<=n;i++){
     93             C[i]=(i*C[i-1]%MOD*inv(i-t))%MOD;
     94         }
     95         mem(cnt,0);
     96         for(i=0;i<n;i++){
     97             scanf("%d",&a);
     98             cnt[a]++;
     99         }
    100         for(i=m;i>=1;i--){
    101             tot=cnt[i];s=0;
    102             for(j=i+i;j<=m;j+=i){
    103                 tot+=cnt[j];
    104                 s=(s+ans[j])%MOD;
    105             }
    106             if(t>tot)ans[i]=0;
    107             else {
    108                 p=m/i;
    109                 ans[i]=(C[tot]*mulpow(p-1,tot-t)%MOD*mulpow(p,n-tot))%MOD;
    110                 ans[i]=(ans[i]-s+MOD)%MOD;
    111             }
    112         }
    113 
    114         printf("%I64d",ans[1]);
    115         for(i=2;i<=m;i++)
    116             printf(" %I64d",ans[i]);
    117         putchar('
    ');
    118     }
    119     return 0;
    120 }
  • 相关阅读:
    hdu 1455 N个短木棒 拼成长度相等的几根长木棒 (DFS)
    hdu 1181 以b开头m结尾的咒语 (DFS)
    hdu 1258 从n个数中找和为t的组合 (DFS)
    hdu 4707 仓鼠 记录深度 (BFS)
    LightOJ 1140 How Many Zeroes? (数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3652 B-number (数位DP)
    HDU 5900 QSC and Master (区间DP)
    HDU 5901 Count primes (模板题)
    CodeForces 712C Memory and De-Evolution (贪心+暴力)
  • 原文地址:https://www.cnblogs.com/zhsl/p/3258772.html
Copyright © 2011-2022 走看看