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

#871. GCD

题意:给定 1 ≤ a < m ≤ 1 0 10 1\leq a<m\leq 10^{10} 1a<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 , a − b ) \gcd(a,b)=\gcd(a,a+b)=\gcd(a,a-b) gcd(a,b)=gcd(a,a+b)=gcd(a,ab) ,两个数的和或差的 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)\Rightarrow 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;
}

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'<i,1\leq j'<j}{dp(i',j')+1} 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值