zoukankan      html  css  js  c++  java
  • codeforeces 547C

    题目:给出若干数,然后若干组询问,每次询问一个数,如果这个数存在,那么删去这个数,如果没有,添加这个数,每次询问后输出此时已经有的数中互质的有多少对。

    思路:利用容斥原理求出已经有的数中与正在询问的数不互质的数的数目。先对所有数进行质数分解。然后通过含有的不同质数对所有数字进行分类。之后就可以用容斥原理统计数目。因为质数的数目实际上不大(每个数的质因子数目实际上很小)所以此类题可以直接用dfs。

    PS:此题暴露出了在数学题上的若干细节问题,改了一上午。。。

    #include<iostream>
    #include<map>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<functional>
    #include<set>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> P;
    const int maxv=5e5+400;
    vector<int> G[maxv];
    vector<int> pri;
    bool p[maxv];
    set<int> beer;
    int f[maxv],c[maxv],a[maxv];
    int n,q;
    void init(){
        for(int i=2;i<maxv;i++){
            if(!p[i]) pri.pb(i);
            for(int j=0;j<pri.size()&&i*pri[j]<maxv;j++){
                p[i*pri[j]]=1;
                if(i%pri[j]==0) break;
            }
        }
    }
    void getp(){
        for(int i=0;i<n;i++){
            int x=a[i];
            int h=0;
            while(x>1&&pri[h]*pri[h]<=x){
                if(x%pri[h]==0){
                    G[i].pb(pri[h]);
                    while(x>1&&x%pri[h]==0) x/=pri[h];
                }
                h++;
            }
            if(x!=1) G[i].pb(x);
        }
    }
    void read(){
        cin>>n>>q;
        for(int i=0;i<n;i++) scanf("%d",a+i);
    }
    ll ans=0;
    int top=0;
    void dfs(int t,int x,int cont,int flag,int val){
        if(t>=(int)G[x].size()){
            if(cont==0) return;
            ans+=f[val]*flag;
            c[top++]=val;
            return;
        }
        dfs(t+1,x,cont,flag,val);
        dfs(t+1,x,cont+1,flag*-1,val*G[x][t]);
    }
    void solve(){
        int x;
        while(q--){
            scanf("%d",&x);
            x--;
            if(a[x]==1){
                if(beer.find(x)!=beer.end()){
                    beer.erase(x);
                    ans-=beer.size();
                }else{
                    ans+=beer.size();
                    beer.insert(x);
                }
            }else{
                if(beer.find(x)!=beer.end()){
                    beer.erase(x);
                    ans-=beer.size();
                    top=0;
                    dfs(0,x,0,-1,1);
                    ans--;
                    beer.erase(x);
                    for(int i=0;i<top;i++) f[c[i]]--;
                }else{
                    top=0;
                    ans+=beer.size();
                    dfs(0,x,0,1,1);
                    beer.insert(x);
                    for(int i=0;i<top;i++) f[c[i]]++;
                }
            }
            printf("%lld
    ",ans);
        }
    }
    int main(){
        //freopen("/home/files/CppFiles/in","r",stdin);
        init();
        read();
        getp();
        solve();
        return 0;
    }
    View Code
  • 相关阅读:
    Libevent源码分析系列
    TCP检验和
    Redis—数据结构之list
    STL—list
    STL—vector
    STL—vector空间的动态增长
    STL—内存的配置与释放
    Actuator 未授权访问之heapdump利用
    Git submodule update 命令执行
    利用Haproxy搭建 HTTP 请求走私(Request smuggling)环境
  • 原文地址:https://www.cnblogs.com/Cw-trip/p/4642769.html
Copyright © 2011-2022 走看看