• 区间乘积的因子数之和


    题目链接

    题意:
    给定一个长度为 n n n 的数组 a a a,数组中每个数都是不大于 3 3 3 的正整数。已知一个区间的权值为该区间所有数乘积的因子数量,求所有区间的权值之和。答案对 1 e 9 + 7 1e9+7 1e9+7 取模。

    数据范围:
    1 ≤ n ≤ 1 0 5 1\leq n\leq 10^5 1n105
    1 ≤ a i ≤ 3 1\leq a_i\leq 3 1ai3

    题解:
    一个数 x x x 的因子数量为:
    x x x 拆成所有质因子的乘积形式,统计每种质因子的个数,第 i i i 个质因子 p i p_i pi 的数量为 c n t p i cnt_{p_i} cntpi
    那么数 x x x 的因子数量为: ∏ i = 1 ( c n t p i + 1 ) \prod\limits_{i=1} (cnt_{p_i}+1) i=1(cntpi+1)

    p r e 2 i = ∑ j = 1 i [ a j = 2 ] pre2_i = \sum\limits_{j=1}^i [a_j=2] pre2i=j=1i[aj=2] p r e 3 i = ∑ j = 1 i [ a j = 3 ] pre3_i = \sum\limits_{j=1}^i [a_j=3] pre3i=j=1i[aj=3]

    p p r e 2 i = ∑ j = 1 i p r e 2 j ppre2_i = \sum\limits_{j=1}^i pre2_j ppre2i=j=1ipre2j p p r e 3 i = ∑ j = 1 i p r e 3 j ppre3_i=\sum\limits_{j=1}^i pre3_j ppre3i=j=1ipre3j

    m u l 2 3 i = ∑ j = 1 i p r e 2 j × p r e 3 j mul23_i = \sum\limits _{j=1}^{i}pre2_j\times pre3_j mul23i=j=1ipre2j×pre3j

    对于题目中的区间权值,等价于 ( p r e 2 + 1 ) × ( p r e 3 + 1 ) (pre2+1)\times (pre3+1) (pre2+1)×(pre3+1)

    所以本题求的就是: ∑ r = 1 n ∑ l = 1 r ( p r e 2 r − p r e 2 l − 1 + 1 ) × ( p r e 3 r − p r e 3 l − 1 + 1 ) \sum\limits_{r=1}^{n}\sum\limits_{l=1}^{r} (pre2_r-pre2_{l-1}+1)\times (pre3_r-pre3_{l-1}+1) r=1nl=1r(pre2rpre2l1+1)×(pre3rpre3l1+1)

    化简:
    ( p r e 2 r − p r e 2 l − 1 + 1 ) × ( p r e 3 r − p r e 3 l − 1 + 1 ) = p r e 2 r × p r e 3 r − p r e 2 r × p r e 3 l − 1 + p r e 2 r − p r e 2 l − 1 × p r e 3 r + p r e 2 l − 1 × p r e 3 l − 1 − p r e 2 l − 1 + p r e 3 r − p r e 3 l − 1 + 1 = ( p r e 2 r × p r e 3 r + p r e 2 r + p r e 3 r + 1 ) ① + ( p r e 2 l − 1 × p r e 3 l − 1 ) ② − ( p r e 2 l − 1 × ( p r e 3 r + 1 ) + p r e 3 l − 1 × ( p r e 2 r + 1 ) ) ③ (pre2_r-pre2_{l-1}+1)\times (pre3_r-pre3_{l-1}+1) \\ =pre2_r\times pre3_r - pre2_r\times pre3_{l-1}+pre2_r-pre2_{l-1}\times pre3_r+pre2_{l-1}\times pre3_{l-1}-pre2_{l-1}+ pre3_r-pre3_{l-1}+1 \\ = (pre2_r\times pre3_r+pre2_r+pre3_r+1)_{①}+(pre2_{l-1}\times pre3_{l-1})_{②}-(pre2_{l-1}\times (pre3_r+1)+pre3_{l-1}\times (pre2_r+1))_{③} (pre2rpre2l1+1)×(pre3rpre3l1+1)=pre2r×pre3rpre2r×pre3l1+pre2rpre2l1×pre3r+pre2l1×pre3l1pre2l1+pre3rpre3l1+1=(pre2r×pre3r+pre2r+pre3r+1)+(pre2l1×pre3l1)(pre2l1×(pre3r+1)+pre3l1×(pre2r+1))

    对上述三个表达式分别求和:
    ∑ r = 1 n ∑ l = 1 r ( p r e 2 r × p r e 3 r + p r e 2 r + p r e 3 r + 1 ) = ∑ r = 1 n r × ( p r e 2 r × p r e 3 r + p r e 2 r + p r e 3 r + 1 ) \sum\limits_{r=1}^{n}\sum\limits_{l=1}^{r} (pre2_r\times pre3_r+pre2_r+pre3_r+1)\\ =\sum\limits_{r=1}^{n} r\times (pre2_r\times pre3_r+pre2_r+pre3_r+1) r=1nl=1r(pre2r×pre3r+pre2r+pre3r+1)=r=1nr×(pre2r×pre3r+pre2r+pre3r+1)

    ∑ r = 1 n ∑ l = 1 r ( p r e 2 l − 1 × p r e 3 l − 1 ) = ∑ r = 1 n m u l 2 3 r − 1 \sum\limits_{r=1}^{n}\sum\limits_{l=1}^{r} (pre2_{l-1}\times pre3_{l-1}) \\ = \sum\limits_{r=1}^{n}mul23_{r-1} r=1nl=1r(pre2l1×pre3l1)=r=1nmul23r1

    ∑ r = 1 n ∑ l = 1 r − ( p r e 2 l − 1 × ( p r e 3 r + 1 ) + p r e 3 l − 1 × ( p r e 2 r + 1 ) ) = − ∑ r = 1 n ∑ l = 1 r   ( p r e 2 l − 1 × ( p r e 3 r + 1 ) + p r e 3 l − 1 × ( p r e 2 r + 1 ) ) = − ∑ r = 1 n ( p p r e 2 r − 1 × ( p r e 3 r + 1 ) + p p r e 3 r − 1 × ( p r e 2 r + 1 ) ) \sum\limits_{r=1}^{n}\sum\limits_{l=1}^{r} -(pre2_{l-1}\times (pre3_r+1)+pre3_{l-1}\times (pre2_r+1)) \\ =-\sum\limits_{r=1}^{n}\sum\limits_{l=1}^{r} \ (pre2_{l-1}\times (pre3_r+1)+pre3_{l-1}\times (pre2_r+1)) \\ =-\sum\limits_{r=1}^{n} (ppre2_{r-1}\times (pre3_r+1)+ppre3_{r-1}\times (pre2_r+1)) r=1nl=1r(pre2l1×(pre3r+1)+pre3l1×(pre2r+1))=r=1nl=1r (pre2l1×(pre3r+1)+pre3l1×(pre2r+1))=r=1n(ppre2r1×(pre3r+1)+ppre3r1×(pre2r+1))

    均可以在 O ( n ) O(n) O(n) 时间复杂度内完成。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int mod = 1e9 + 7;
    const int N = 100010;
    int a[N], n;
    int pre2[N], ppre2[N];
    int pre3[N], ppre3[N];
    int mul23[N];
    
    void add(int& a, int b) {
    	a = (a + b) % mod;
    	if (a < 0) a += mod;
    }
    
    int main()
    {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    	for (int i = 1; i <= n; ++i) {
    		pre2[i] = pre2[i - 1];
    		pre3[i] = pre3[i - 1];
    		
    		if (a[i] == 2) {
    			add(pre2[i], 1);
    		} else if (a[i] == 3) {
    			add(pre3[i], 1);
    		}
    		
    		ppre2[i] = ppre2[i - 1];
    		ppre3[i] = ppre3[i - 1];
    		add(ppre2[i], pre2[i]);
    		add(ppre3[i], pre3[i]);
    		
    		mul23[i] = mul23[i - 1];
    		add(mul23[i], 1ll * pre2[i] * pre3[i] % mod);
    	}
    	
    	int ans = 0;
    	for (int i = 1; i <= n; ++i) {
    		int temp = 0;
    		add(temp, 1ll * pre2[i] * pre3[i] % mod);
    		add(temp, pre2[i]);
    		add(temp, pre3[i]);
    		add(temp, 1);
    		add(ans, 1ll * i * temp % mod);
    
    		add(ans, -1ll * (1 + pre3[i]) * ppre2[i - 1] % mod);
    		add(ans, -1ll * (1 + pre2[i]) * ppre3[i - 1] % mod);
    		add(ans, mul23[i - 1]);
    	}
    	
    	printf("%d\n", ans);
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
  • 相关阅读:
    leetcode-数组系列算法总结
    Java中23种设计模式-单例模式--工厂模式
    想玩转监控神器Prometheus吗?
    HTML网页设计制作——响应式网页影视动漫资讯bootstrap网页(9页)
    windows11使用docker部署安装minio
    flutter pod install, Error installing FMDB
    Android打造专有hook第二篇,走进规范第一步
    MATLAB程序设计与应用 3.5 稀疏矩阵
    Java案例——控制台实现QuickHit小游戏
    架构:C4 Model
  • 原文地址:https://blog.csdn.net/weixin_43900869/article/details/125492104