zoukankan      html  css  js  c++  java
  • Codeforces 1097F. Alex and a TV Show

    传送门

    由于只要考虑 $mod 2$ 意义下的答案,所以我们只要维护一堆的 $01$ 

    容易想到用 $bitset$ 瞎搞...,发现当复杂度 $qv/32$ 是可以过的...

    一开始容易想到对每个集合开一个 $bitset$ ,叫 $cnt[]$ ,维护各种值的数出现了奇数还是偶数次

    因为要维护那个奇怪的 $3$ 操作,所以改成维护各种值的倍数出现了奇数还是偶数次,即

    $cnt[x]$ 维护集合内所有 $x|d$ 的数 $d$ 的出现次数

    那么对于操作 $3$,$x$ 的倍数和 $y$ 的倍数相乘后 $x$ 的倍数和 $y$ 的倍数数量都是 $cnt[x] cdot cnt[y]$

    然后就可以很容易维护了,因为只有 $0,1$ 那么其实相当于把两个 $bitset$ 取 $ ext{'&'}$ 即可

    同时对于操作 $2$ ,显然只要对 $bitset$ 取 $ ext{'^'}$ 就行

    然后操作 $1$ ,直接把 $bitset$ 清空,然后设集合内的数为 $d$ ,那么直接根号筛一下 $d$ 的因数 $x$ 然后 $cnt[x]=1$ 即可

    最后是操作 $4$ ,因为我们维护的是 $x$ 的倍数的出现次数,设 $F(x),f(x)$ 分别为 $x$ 倍数出现次数,$x$ 出现次数

    那么有 $F(x)=sum_{x|d} f(d)$ ,然后就发现了熟悉的莫比乌斯反演,我们知道 $F$ 想求 $f$,直接反演可得

    $f(x)=sum_{x|d} mu (frac{d}{x}) F(d)$ ,由于 $mod 2$ 意义下 $-1 equiv 1$ 所以可以用 $bitset$ 维护一下每个 $x$ 的所有 $x|d$ 的 $mu(d/x)$

    即设 $bitset$ $g[x]$ 维护一下 $x|d$ 的 $g[x][d]=mu(d/x)$ 然后对于 $4$ 操作 $(4 x v)$ 就是 $(cnt[x]&g[v]).count()&1$ 

    代码不长

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<bitset>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=1e5+7,M=7007;
    int n,Q;
    int pri[M],mu[M],tot;
    bool not_pri[M];
    bitset <M> cnt[N],g[M];
    void init()
    {
        not_pri[1]=1; mu[1]=1;
        for(int i=2;i<M;i++)
        {
            if(!not_pri[i]) pri[++tot]=i,mu[i]=1;
            for(int j=1;j<=tot;j++)
            {
                ll g=1ll*i*pri[j]; if(g>=M) break;
                not_pri[g]=1; if(i%pri[j]==0) break;
                mu[g]=-mu[i];
            }
        }
        for(int i=1;i<M;i++)
            for(int j=i;j<M;j+=i)
                g[i][j]=abs(mu[j/i]);
    }
    int main()
    {
        n=read(),Q=read(); init();
        int a,b,c,d;
        while(Q--)
        {
            a=read(),b=read(),c=read();
            if(a==1)
            {
                cnt[b]=0; int T=sqrt(c);
                for(int i=1;i<=T;i++)
                    if(c%i==0) cnt[b][i]=cnt[b][c/i]=1;
            }
            else if(a==2) d=read(),cnt[b]=cnt[c]^cnt[d];
            else if(a==3) d=read(),cnt[b]=cnt[c]&cnt[d];
            else printf("%d",int((cnt[b]&g[c]).count())&1);
        }
        puts(""); return 0;
    }
  • 相关阅读:
    Postman请求Https接口与认证
    HTML实用
    ORM实例教程_转
    web跨域问题CORS
    gin入门
    swagger应用
    k8s之容器
    腾讯高级工程师:如何从头开始写游戏服务器框架_转
    tensorflow入门
    sublime Text 3实用功能和常用快捷键收集
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11731352.html
Copyright © 2011-2022 走看看