题目链接:http://codeforces.com/problemset/problem/402/D
/**算法分析: */ #include<bits/stdc++.h> #define MAXN 5005 #define MAXM 110000 #define PI acos(-1.0) #define REP(i,n) for(int i=0; i<n; i++) #define FOR(i,s,t) for(int i=s; i<=t; i++) #define mem(a,b) memset(a,b,sizeof(a)) #define show(x) { cerr<<">>>"<<#x<<" = "<<x<<endl; } #define showtwo(x,y) { cerr<<">>>"<<#x<<"="<<x<<" "<<#y<<" = "<<y<<endl; } using namespace std; int prime[MAXM],prime_index; int a[MAXN],gcd[MAXN]; int n,m; set<int> badset; map<int,int> vis; void get_prime() { prime_index = 0; bool flag[MAXM]; mem(flag,0); FOR(i,2,MAXM-1) { if(!flag[i]) { prime[prime_index++] = i; for(int j=i+i; j<MAXM; j+=i) flag[j] = true; } } } int F(int s) { int ret = 0,rcd = s; //这个rcd十分重要,注意改变的数如果还要操作就需要记录 if(badset.count(s)) return -1; if(vis.find(s) != vis.end()) return vis[s]; //进行因式分解,一种预处理出质数,另一种直接sqrt(n); /** for(int i=0; i < prime_index && prime[i]*prime[i] <= s; i++) { int p = prime[i]; if(s % p == 0) { int isbad; if(badset.count(p)) isbad = -1; else isbad = 1; while(s % p == 0) ret += isbad, s /= p; } } */ for(int i=2; i*i <= s; i++) { int p = i; if(s % p == 0) { int isbad; if(badset.count(p)) isbad = -1; else isbad = 1; while(s % p == 0) ret += isbad, s /= p; } } if(s != 1) { if(badset.count(s)) ret--; else ret++; } return vis[rcd] = ret; } int main() { // freopen("E:\acm\input.txt","r",stdin); // get_prime(); cin>>n>>m; FOR(i,1,n) scanf("%d",&a[i]); FOR(i,1,m) { int tmp; scanf("%d",&tmp); badset.insert(tmp); } int ans = 0; gcd[0] = a[1]; FOR(i,1,n) { ans += F(a[i]); gcd[i] = __gcd(gcd[i-1],a[i]); } int decr = 0; for(int i=n; i>=1; i--) { int cur_f = F(gcd[i]) + decr; if(cur_f < 0) { ans -= cur_f * i; decr -= cur_f; } } cout<<ans<<endl; }