解題報告:HDU_5656 CA Loves GCD DP

題目鏈接


題意:

給n個不同的數,求所有非空子集的gcd之和


思路:

dp[ i ] 表示 gcd 爲 i 的子集數

每讀入一個新的數x,可以如果將x與gcd爲i的放在一起會導致gcd(x,i)的方案數增加dp[ i ] 種

如果 i = x,那麼還會額外多一種方案(只放x)。

因爲 較小的gcd(x,i)可能會用到同階段的較大的 i ,所有操作順序要從小到大。


代碼:

#include<bits/stdc++.h>

const long long mod = 1e8+7;
using namespace std;
const int N = 1005;
int dp[N];

int main()
{
   int T;
   scanf("%d",&T);
   while(T--){
      memset(dp,0,sizeof(dp));
      int n,x,m = 0;
      scanf("%d",&n);
      while(n--){
         scanf("%d",&x);
         m = max(m,x);
         for(int i=1;i<=m;i++){
            if(i==x)dp[i] = ( ( dp[i]*2 ) + 1 ) % mod;
            else if(dp[i]){
               int j = __gcd(i,x);
               dp[j] = (dp[j] + dp[i]) % mod;
            }
         }
      }long long ans =0;
      for(int i=1;i<=m;i++){
         ans = (ans + 1LL * i * dp[i] % mod)% mod;
      }printf("%I64d\n",ans);
   }return 0;
}









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章