1. 程式人生 > >Codeforces Round #523 (Div. 2) C Multiplicity

Codeforces Round #523 (Div. 2) C Multiplicity

傳送門

https://www.cnblogs.com/violet-acmer/p/10005351.html

 

題意:

  給定一陣列a[],從a[ ]中除去任意個元素得到b[ ],求能形成多少“好序列”;

  好序列的定義是:對於任意的 i 有 b[i]%i == 0(1 ≤ i ≤ size_b[ ])。

題解:

  相關變數解釋:

1 int n;
2 int a[maxn];
3 int dp[maxn];//dp[i] : 下標i處可以獲得的最大的"好序列"
4 int factor[maxn];//factor[i] : 記錄a[i]的因子

  步驟:

   (1):從a[1]開始遍歷整個陣列;

   (2):來到a[i]處,將a[i]因式分解,找到其所有的因子factor,並判斷其是否在[1,i ]範圍內,如果在dp[factor] += dp[factor-1];(對於所有的factor)

具體看程式碼:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace
std; 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 const int MOD=1e9+7; 9 const int maxn=1e5+10; 10 11 int n; 12 int a[maxn]; 13 int dp[maxn];//dp[i] : 下標i處可以獲得的最大的"好序列" 14 int factor[maxn];//factor[i] : 記錄a[i]的因子 15 16 void updataDp(int i) 17 { 18 int index=1; 19 for(int j=1;j*j <= a[i];++j)
20 { 21 if(a[i]%j == 0)//判斷j是否為a[i]的因子 22 { 23 factor[index++]=j;//記錄a[i]的因子 24 if(a[i]/j != j && a[i]/j <= i)//判斷其另一個因子a[i]/j是否 <= i,並判斷其是否等於 j 25 factor[index++]=a[i]/j; 26 } 27 } 28 sort(factor+1,factor+index); 29 for(int j=index-1;j >= 1;--j)//從大因子到小因子,防止a[i]的小因子影響大因子 30 { 31 int x=factor[j]; 32 dp[x] += dp[x-1]; 33 dp[x] %= MOD; 34 } 35 } 36 int Solve() 37 { 38 mem(dp,0); 39 dp[0]=1; 40 for(int i=1;i <= n;++i)//遍歷a[] 41 updataDp(i);//由a[i]更新dp[] 42 43 int res=0; 44 for(int i=1;i <= n;++i) 45 res=res%MOD+dp[i]; 46 47 return res%MOD; 48 } 49 int main() 50 { 51 scanf("%d",&n); 52 for(int i=1;i <= n;++i) 53 scanf("%d",a+i); 54 printf("%d\n",Solve()); 55 }
View Code

  AC前的錯誤程式碼分析:

  ①:從小因子到大因子更新dp[ ],在第五組資料就wa了

1 void updataDp(int i)
2 {
3     for(int j=1;j < i;++j)
4         if(a[i]%(j+1) == 0)
5             dp[j+1] += dp[j],dp[j+1] %= MOD;
6     dp[1]++;
7 }

  錯誤原因:根據dp定義,dp[ i ]指的是當前元素a[i]在去點其之前的若干個元素後可以形成的“好序列”個數,終點是“其之前”,如果從小因子到大因子更新dp[ ],

  dp[bigFactor] += dp[bigFactor-1];如果bigFactor-1是a[i]的因子,那麼這個因子就會給dp[bigFactor]做貢獻,而實際是不需要。

  ②:查詢a[i]的因子是從1遍歷到i,在第八組資料TLE

  此演算法的時間複雜度為O(N^2),當然會TLE了,然後,實在是沒轍了,就去翻了翻大佬部落格,發現這篇部落格上使用vector儲存的a[i]的所有因子,在查詢a[ i ]的所有因子時的時間複雜度是sqrt(n),當我看到sort排序的時候有點納悶,加個O(nlogn)的排序難道不超時?

  後來仔細想了一下,a[ i ]的所有因子很少(106才49個因子),所以用sort頂多是O(1)的時間複雜度,而整體時間複雜度為O(n√n),當然就輕輕鬆鬆的A掉了......