• NOIP模拟 gcd 数学


    题面不给……题意:动态增减集合中元素个数,动态求$gcd(i,j)==1$的数的个数。

    坦白地讲题解并没完全看懂……于是听$lc$开了一会车(快开完时$xyz$强行砸场导致烂尾),结合着自己理解又推一遍想明白了……

    在本题之中,我们设$f(x)$为$gcd(i,j)==x$的数的个数,$g(x)$为$gcd(i,j)==kx$的数的个数。很显然$f(x)=g(x)-f(2x)-f(3x)...$,这样推下去,我们就会发现这个系数其实是符合莫比乌斯函数的,最后大力化简就是:

    [ sum_{d}^{} {μ(d)*g(d)} =f(d)]。

    现在定义$s(i)$为当前选中的集合中为$i$倍数数的个数,可以看出,$g(i)=s(i)*(s(i)-1)/2$。

    然后我们就可以预处理莫比乌斯函数,在每一次修改元素个数时候动态维护$s(i)$。

    但是我们暴力求$ans$显然会$T$……于是考虑每一次加入或删除元素对于最后结果贡献。

    当我们插入一个元素,对于每一个可以整除它的$i$,$Δans=μ(i)*((s(i)+1)*s(i)-s(i)*(s(i)-1))/2=μ(i)s(i)$。同理,删除时,对于每一个这样的$i$,$Δans=μ(i)*((s(i)-2)*(s(i)-1)-s(i)*(s(i)-1))/2=-μ(i)(s(i)-1)$。然后我们根据这个规律转移即可。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn=200005,maxx=500005;
     7 bool notprime[maxx];int prime[maxx],cnt,mu[maxx];
     8 void init()
     9 {
    10     mu[1]=1;
    11     for(int i=2;i<=500000;i++)
    12     {
    13         if(!notprime[i])prime[++cnt]=i,mu[i]=-1;
    14         for(int j=1;j<=cnt&&i*prime[j]<=500000;j++)
    15         {
    16             notprime[i*prime[j]]=1;
    17             if(i%prime[j])mu[i*prime[j]]=-mu[i];
    18             else {mu[i*prime[j]]=0;break;}
    19         }
    20     }
    21 }
    22 int n,m,a[maxn],s[maxx],maxv,t[maxn];
    23 int haha()
    24 {
    25     scanf("%d%d",&n,&m);init();
    26     for(int i=1;i<=n;i++)scanf("%d",&a[i]),maxv=max(maxv,a[i]);
    27     long long ans=0;
    28     for(int i=1;i<=m;i++)
    29     {
    30         int x;scanf("%d",&x);int sgn=t[x]?-1:1;
    31         for(int j=1;j*j<=a[x];j++)
    32             if(!(a[x]%j))
    33             {
    34                 if(sgn==1)ans+=1ll*mu[j]*s[j];else ans-=1ll*(s[j]-1)*mu[j];s[j]+=sgn*1;
    35                 if(j*j<a[x])
    36                 {
    37                     if(sgn==1)ans+=1ll*mu[a[x]/j]*s[a[x]/j];else ans-=1ll*(s[a[x]/j]-1)*mu[a[x]/j];
    38                     s[a[x]/j]+=sgn*1;
    39                 }
    40             }
    41         t[x]^=1;
    42         printf("%lld
    ",ans);
    43     }
    44 }
    45 int sb=haha();
    46 int main(){;}
    C
  • 相关阅读:
    sql 随机获取100条数据
    NPOI导出信息
    JavaScript打印页面
    生僻字在页面上不显示(䶮)
    C# 下载文件并使用指定名称展示
    layui 表格列编辑获取编辑前的值然后重新赋值,并通过键盘控制编辑位置
    C# 网络图片转base64
    C# WebApi debug模式下编译没有问题,切换到release模式下编译就有异常,但是依旧能生成成功,再切回到debug模式也会报错,也可以生成成功
    HTTP/2
    Class的继承
  • 原文地址:https://www.cnblogs.com/Loser-of-Life/p/7624577.html
Copyright © 2020-2023  润新知