• 【8.5】代码源 - 【GCD】【序列中位数】【最大连边数量】


    #871. GCD

    题意:给定 1 ≤ a < m ≤ 1 0 10 1\leq a1a<m1010 ,计算 ∑ x = 0 m − 1 [ gcd ⁡ ( a , m ) = gcd ⁡ ( a + x , m ) ] \sum_{x=0}^{m-1}{[\gcd(a,m)=\gcd(a+x,m)]} x=0m1[gcd(a,m)=gcd(a+x,m)]

    题解:(区间互质) 代码源每日一题 Div1 GCD

    思路:推一下式子:

    容易知道 k = gcd ⁡ ( a , m ) k=\gcd(a,m) k=gcd(a,m) 一定是 m m m 的因子。我们先计算出 a + x a+x a+x 的范围内是 k k k 的倍数的左右边界,倍数范围即为 [ l , r ] = [ ⌈ a k ⌉ , ⌊ a + m − 1 k ⌋ ] [l,r]=[\left \lceil \frac a k \right \rceil,\left \lfloor \frac{a+m-1} k \right \rfloor] [l,r]=[ka,ka+m1] 。那么 ∑ x = 0 m − 1 [ gcd ⁡ ( a , m ) = gcd ⁡ ( a + x , m ) ] = ∑ i = l r [ gcd ⁡ ( i , m k ) = 1 ] \sum_{x=0}^{m-1}{[\gcd(a,m)=\gcd(a+x,m)]}=\sum_{i=l}^r{[\gcd(i,\frac m k)=1]} x=0m1[gcd(a,m)=gcd(a+x,m)]=i=lr[gcd(i,km)=1] ,那么问题转化为求 l ∼ r l\sim r lr 中有多少个数与 m k \frac m k km 互质。

    一个经典的问题就是求 1 ∼ n 1\sim n 1n 有多少个数与 m m m 互质,方法为:对 m m m 分解质因子,然后二进制枚举容斥计算,时间复杂度 O ( n + 2 11 ) O(\sqrt n+2^{11}) O(n +211) ,这里的 11 11 11 是指 1 0 10 10^{10} 1010 内的数字最多有 11 11 11 个质因子。

    总结了一些关于 gcd ⁡ \gcd gcd 的性质:

    gcd ⁡ ( a , b ) = gcd ⁡ ( a , a + b ) \gcd(a,b)=\gcd(a,a+b) gcd(a,b)=gcd(a,a+b) ,序列的前缀和序列或差分序列的 gcd ⁡ \gcd gcd 相等
    gcd ⁡ ( k × a , k × b ) = k × gcd ⁡ ( a , b ) \gcd(k\times a,k\times b)=k \times \gcd(a,b) gcd(k×a,k×b)=k×gcd(a,b)
    gcd ⁡ ( a , b ) = p × gcd ⁡ ( a p , b p ) \gcd(a,b)=p\times \gcd(\frac a p,\frac b p) gcd(a,b)=p×gcd(pa,pb) ,要保证 p p p a , b a,b a,b 的因子
    gcd ⁡ ( a k , b k ) = gcd ⁡ k ( a , b ) \gcd(a^k,b^k)=\gcd^k(a,b) gcd(ak,bk)=gcdk(a,b)
    c ∣ a × b ⇒ c gcd ⁡ ( b , c ) ∣ a c|a\times b\Rightarrow \frac c{\gcd(b,c)}|a ca×bgcd(b,c)ca

    模板:

    LL cal(LL n, LL m){ // numbers of i in 1 ~ n : gcd(i, m) == 1
        vector<LL> vec;
        for(LL i = 2; i * i <= m; i ++ ){
            if(m % i == 0){
                while(m % i == 0) m /= i;
                vec.pb(i);
            }
        }
        if(m > 1) vec.pb(m);
        LL res = 0;
        for(int bit = 1; bit < 1 << vec.size(); bit ++ ){
            LL mul = 1;
            rep(i, 0, (int)vec.size() - 1) if(bit >> i & 1) mul *= vec[i];
            if(__builtin_popcount(bit) & 1) res += n / mul;
            else res -= n / mul;
        }
        return n - res;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    AC代码:http://oj.daimayuan.top/submission/321288


    #877. 序列中位数

    题意:给定正整数 N N N , 求出 1 ∼ N − 1 1∼N−1 1N1 中所有与 N N N 互质的数构成的序列 的中位数.

    我们定义 : 一个长度为 K K K 的序列的中位数是序列中第 ⌊ K + 1 2 ⌋ ⌊\frac{K+1}2⌋ 2K+1 大的数字. 且两个正整数 a a a b b b 互质当且仅当 gcd ⁡ ( a , b ) = 1 \gcd(a,b)=1 gcd(a,b)=1

    思路:打表可以发现规律。证明的话: gcd ⁡ ( i , x ) = gcd ⁡ ( x − i , x ) \gcd(i,x)=\gcd(x-i,x) gcd(i,x)=gcd(xi,x) ,大概就是这个式子。

    AC代码:http://oj.daimayuan.top/submission/322050


    #916. 最大连边数量

    题意: 1 ≤ n ≤ 1 0 5 1\leq n\leq 10^5 1n105

    在这里插入图片描述
    题解:(树状数组/DP) 代码源每日一题 最大连边数量

    思路:树状数组优化 DP 。

    我们按照下标枚举 a a a 里的元素,去枚举 b b b 里对应的元素。我们先定义 d p ( i , j ) dp(i,j) dp(i,j) 表示 a a a i i i 个元素和 b b b j j j 个元素的最大匹配,转移方程为 d p ( i , j ) = max ⁡ 1 ≤ i ′ < i , 1 ≤ j ′ < j d p ( i ′ , j ′ ) + 1 dp(i,j)=\max_{1\leq i'dp(i,j)=max1i<i,1j<jdp(i,j)+1

    可以发现这是个二维偏序,第一维能被优化。对于和当前枚举的 i i i 对应的 j j j ,转移方程为 d p ( j ) = max ⁡ ( d p ′ ( j ) , max ⁡ k = 1 j − 1 d p ′ ( k ) + 1 ) dp(j)=\max(dp'(j),\max_{k=1}^{j-1}dp'(k)+1) dp(j)=max(dp(j),maxk=1j1dp(k)+1) ,用树状数组维护第二维的前缀最值即可即可。

    AC代码:http://oj.daimayuan.top/submission/322797

  • 相关阅读:
    【python】flask中如何向https服务器传输信息
    开源项目ChatGPT-website再次更新,累计下载使用1600+
    分页查询实体和分页响应实体的使用
    数据结构:链表
    DLG4NLP
    【毕业设计】基于java的健康食谱推荐小程序源码
    本人开发Android视频编码和直播推流使用到的相关命令
    18、优化网站性能
    Stanford CS143 速通PA2教程
    latex入门笔记
  • 原文地址:https://blog.csdn.net/weixin_51948235/article/details/126198852