#P2718. 第3题-二维矩阵
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 17
            Accepted: 4
            Difficulty: 7
            
          
          
          
                       所属公司 : 
                              阿里
                                
            
                        
              时间 :2025年3月20日-阿里云(开发岗)
                              
                      
          
 
- 
                        算法标签>数学          
 
第3题-二维矩阵
思路
题目要求求所有子矩阵中元素之和。已知对于一个 n×n 的矩阵,元素 c[i][j](下标从 1 开始)出现在所有连续子矩阵中的次数为
因此所有子矩阵的和为

注意 c[i][j]=a[i]⊕b[j] 对于二进制数可写为

设
- 权值 wi=i×(n−i+1)(注意题目中下标从1开始,若使用0-index需转换为 (i+1)×(n−i))
 - S=∑i=1nwi
 - Sa=∑i=1na[i]×wi
 - Sb=∑j=1nb[j]×wj
 
则有
![]()
代码实现
C++
#include <iostream>
#include <vector>
using namespace std;
 
const long long MOD = 1000000007;
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    cin >> n;
    vector<int> a(n), b(n);
    for (int i = 0; i < n; i++){
        cin >> a[i];
    }
    for (int i = 0; i < n; i++){
        cin >> b[i];
    }
    
    long long S = 0, S_a = 0, S_b = 0;
    // 注意下标转换:题中下标从1开始,因此对于数组下标 i(0-indexed)对应权值为 (i+1)*(n-i)
    for (int i = 0; i < n; i++){
        long long weight = (long long)(i+1) * (n - i) % MOD;
        S = (S + weight) % MOD;
        if(a[i] == 1)
            S_a = (S_a + weight) % MOD;
        if(b[i] == 1)
            S_b = (S_b + weight) % MOD;
    }
    
    long long ans = (S * ((S_a + S_b) % MOD) % MOD - 2LL * S_a % MOD * S_b % MOD) % MOD;
    if(ans < 0) ans += MOD;
    cout << ans << "\n";
    return 0;
}
java
import java.util.Scanner;
public class Main {
    static final long MOD = 1000000007;
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        int[] b = new int[n];
        
        for (int i = 0; i < n; i++){
            a[i] = sc.nextInt();
        }
        for (int i = 0; i < n; i++){
            b[i] = sc.nextInt();
        }
        
        long S = 0, S_a = 0, S_b = 0;
        // 下标转换:对应权值为 (i+1)*(n-i)
        for (int i = 0; i < n; i++){
            long weight = (long)(i + 1) * (n - i) % MOD;
            S = (S + weight) % MOD;
            if(a[i] == 1)
                S_a = (S_a + weight) % MOD;
            if(b[i] == 1)
                S_b = (S_b + weight) % MOD;
        }
        
        long ans = (S * ((S_a + S_b) % MOD) % MOD - 2L * S_a % MOD * S_b % MOD) % MOD;
        if(ans < 0) ans += MOD;
        
        System.out.println(ans);
        sc.close();
    }
}
python
import sys
MOD = 1000000007
def main():
    n = int(sys.stdin.readline().strip())
    a = list(map(int, sys.stdin.readline().strip().split()))
    b = list(map(int, sys.stdin.readline().strip().split()))
    S, S_a, S_b = 0, 0, 0
    # 下标转换:对应权值为 (i+1)*(n-i)
    for i in range(n):
        weight = (i + 1) * (n - i) % MOD
        S = (S + weight) % MOD
        if a[i] == 1:
            S_a = (S_a + weight) % MOD
        if b[i] == 1:
            S_b = (S_b + weight) % MOD
    ans = (S * ((S_a + S_b) % MOD) % MOD - 2 * S_a % MOD * S_b % MOD) % MOD
    if ans < 0:
        ans += MOD
    print(ans)
if __name__ == "__main__":
    main()
        题目内容
小红有两个长度都为n的数组a,b,仅包含0、1
现在小红生成一个二维矩阵c,满足ci,j=ai⨁bj
现在小红想让你帮助她计算出其所有子矩阵的数值之和,结果对109+7取模。
输入描述
第一行一个整数n(1≤n≤2×105),表示数组长度。
第二行n个整数,第个整数为ai(0≤ai≤1)。
第二行n个整数,第i个整数为bi(0≤bi≤1)。
输出描述
一个整数,表示矩阵c的所有子矩阵之和,结果对109+7取模
样例1
输入
3
1 0 1
0 1 0
输出
52