《 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;
}
View Code

 

posted @ 2021-10-28 10:06  levill  阅读(40)  评论(0编辑  收藏  举报