《 Codeforces Round #305 (Div. 1) C》
直接给结论。令d[x] = 与x互质的数的个数.由容斥原理可得:
d[x] = d[x1] * (-1) ^ f[x1] + d[x2] * (-1) ^ f[x2] + ...
x[i]为x的因子,且质因子都为最低阶,也就是说x[i]是x质因子分解后的质因子组合而成。
我们状压一下所有情况即可。
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> pii; const int N = 2e5 + 5; const int M = 5e5 + 5; const double eps = 1e-6; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 0x3f3f3f #define dbg(ax) cout << "now this num is " << ax << endl; inline long long ADD(long long x,long long y) {return (x + y) % Mod;} inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;} inline long long MUL(long long x,long long y) {return x * y % Mod;} int n,q,a[N],cnt[M]; bool vis[N]; LL ans = 0; vector<int> G[M]; void init() { for(int i = 2;i < M;++i) { if(G[i].size() != 0) continue; for(int j = i;j < M;j += i) G[j].push_back(i); } } LL query(int x) { LL ma = 0; int sz = G[x].size(); for(int i = 0;i < (1 << sz);++i) { int tmp = 1,ct = 0; for(int j = 0;j < sz;++j) { int g = (i >> j) & 1; if(g == 0) continue; tmp *= G[x][j],ct++; } if(ct & 1) ma -= cnt[tmp]; else ma += cnt[tmp]; } return ma; } void update(int x,int id) { int sz = G[x].size(); for(int i = 0;i < (1 << sz);++i) { int tmp = 1; for(int j = 0;j < sz;++j) { int g = (i >> j) & 1; if(g == 0) continue; tmp *= G[x][j]; } cnt[tmp] += id; } } void solve() { init(); scanf("%d %d",&n,&q); for(int i = 1;i <= n;++i) { scanf("%d",&a[i]); } while(q--) { int x;scanf("%d",&x); if(!vis[x]) { ans += query(a[x]); update(a[x],1); vis[x] = 1; } else { update(a[x],-1); ans -= query(a[x]); vis[x] = 0; } printf("%lld\n",ans); } } int main() { //int ca;scanf("%d",&ca); //while(ca--) { solve(); //} // system("pause"); return 0; }