阅读视图

发现新文章,点击刷新页面。

特斯拉的芯片计划可能使其资本支出远超预期

随着特斯拉推进其新的Terafab芯片项目,该公司可能步入一个远超预期的资本支出密集阶段。巴克莱银行表示,这一项目的成本可能会以极快的速度膨胀至非常庞大的规模。该机构指出,特斯拉此前给出的200亿美元资本支出指引现在看来过于保守。(新浪财经)

OpenAI与聚变初创公司Helion洽谈大型能源交易,奥尔特曼辞职避嫌

OpenAI首席执行官山姆·奥尔特曼确认,由于他投资的聚变能源初创公司Helion正在与OpenAI开始探索“开展大规模合作”,他将辞去Helion董事长一职。奥尔特曼在社交媒体上写道,随着两家公司商讨合作,他很难同时在两家公司的董事会中任职。他的辞职将使得两家公司能更加容易地处理相关事宜。据知情人士称,OpenAI可能会确保获得Helion部分聚变能源产出的保障配额,初始为12.5%。目前的谈判集中在OpenAI将在2030年获得5吉瓦的电力,并在2035年扩大到50吉瓦。(财联社)

亚马逊:Leo卫星项目计划加快发射节奏

亚马逊当地时间3月23日宣布,亚马逊Leo卫星项目正持续全面部署,目前已部署超过200颗卫星,另有数百颗已做好发射准备的航天器随时待命。亚马逊称,已做好准备,在第二年加快Leo卫星项目的发展,有望将年发射次数提高一倍以上,达到20次以上,并一次性向太空发射更多卫星。(界面)

房利美与房地美响应特朗普2000亿美元指令,加大MBS购买力度

据知情人士透露,房利美与房地美已开始大规模购入抵押贷款支持证券(MBS),以应对因息差扩大和波动性上升而陷入动荡的市场。此举遵循了美国总统唐纳德·特朗普两个月前发布的一项指令,要求这两家机构购买2000亿美元的MBS,这是其支持住房可负担性并影响抵押贷款市场的更广泛政策的一部分。此番重新入市表明,这两家政府控制的企业或正借近期市场抛售之机,持续重建其债券投资组合。(新浪财经)

汇丰任命首位首席AI官

当地时间3月23日,汇丰控股宣布任命David Rice为其首位首席人工智能官,自4月1日起生效,Rice此前担任该公司的企业及机构银行业务的首席运营官,该职位旨在为公司内部人工智能的应用提供明确的领导。(界面)

Apollo限制旗下私募信贷基金赎回,投资者的申请赎回比例超过11%

Apollo Global Management Inc.限制旗下一只面向零售投资者的大型非上市私募信贷基金的赎回,成为最新一家应对赎回申请激增的另类资管公司。致投资者的信显示,周一,规模250亿美元的商业发展公司(BDC)Apollo Debt Solutions将赎回比例上限设为5%,而客户申请赎回比例达到11.2%。鉴于申请赎回的投资者暂时只能拿回45%的资金,Apollo Debt Solutions向客户返还的资金占申请赎回额的比例低于一些同样启动限赎的同行。(新浪财经)

Alphabet无人机业务挺进密集城区测试

Alphabet旗下无人机部门Wing宣布,今年将开始在旧金山湾区向居民住宅投递包裹,这标志着这家无人机配送部门在其本土市场首次进行商业发布。该公司已在北卡罗来纳州、弗吉尼亚州和澳大利亚开展商业运营。此次向湾区扩张,旨在检验无人机配送能否突破受控的郊区环境,进入监管限制更严、空域情况更复杂、单位经济效益更具挑战性的密集城区。(新浪财经)

雅诗兰黛洽谈收购西班牙Puig,意欲打造美妆巨头

3月24日消息,据报道,雅诗兰黛表示正就收购西班牙美妆时尚集团Puig进行磋商,这笔交易将打造一家年销售额约200亿美元的化妆品巨头。两家公司均拒绝透露具体条款。总部位于西班牙的Puig市值约为90亿欧元。(界面)

OpenAI在投资者文件中将对微软的依赖列为风险

在一份类似IPO招股书的文件中,OpenAI表示,其与微软的紧密关系可能对业务构成潜在风险,并向投资者指出,这家软件公司为其提供了 “相当大一部分融资与算力支持”。这份财务文件是OpenAI在近期创纪录融资轮中向潜在投资者出具的。文件中专门设有 “与交易相关的风险” 和 “与业务相关的风险” 章节。(新浪财经)

今年前两月长江经济带外贸进出口值同比增长19%

今年前两月,长江经济带外贸规模创历史同期新高。据海关统计,11省市外贸进出口值达3.64万亿元,同比增长19%,占全国进出口总值47.1%。其中进口1.32万亿元,出口2.32万亿元。(央视新闻)

美联储4月维持利率不变的概率为92.8%

据CME“美联储观察”:美联储4月加息25个基点的概率为7.2%,维持利率不变的概率为92.8%。美联储到6月累计加息25个基点的概率为9.1%,累计加息50个基点的概率为0.2%,维持利率不变的概率为90.7%。(财联社)

苹果将于6月召开年度全球开发者大会,预计发布一系列AI功能

苹果公司宣布计划6月8-12日举办年度全球开发者大会,届时该公司将展示一系列至关重要的人工智能(AI)功能。苹果公司在周一的声明中表示,本届大会将重点介绍苹果平台的重大更新,包括AI领域的进展以及令人兴奋的新软件和开发者工具。6月8日一场线下主题演讲活动将在苹果总部举行,为大会拉开序幕。(新浪财经)

丰田将投资10亿美元,扩建美国肯塔基、印第安纳州工厂产能

丰田汽车周一宣布,将投资10亿美元用于美国两家工厂的扩建,这是其2030年前在美国本土最高投资100亿美元计划的一部分。此次新增投资中,8亿美元将投向肯塔基州乔治敦工厂,以提升凯美瑞轿车与RAV4跨界车的产能;剩余2亿美元则用于印第安纳州普林斯顿工厂,扩大大汉兰达SUV的产能。(新浪财经)

美股三大指数集体收涨,大型科技股普涨

36氪获悉,3月23日收盘,美股三大指数集体上涨,道指涨1.38%,纳指涨1.38%,标普500指数涨1.15%。大型科技股普涨,甲骨文、特斯拉涨超3%,亚马逊涨超2%,英伟达、Meta、奈飞、苹果涨超1%,谷歌、微软小幅上涨。热门中概股多数上涨,小鹏汽车、蔚来涨超7%,阿里巴巴、理想汽车涨超2%,爱奇艺、微博涨超1%;斗鱼跌超2%,腾讯音乐跌超1%。

每日一题-构造乘积矩阵🟡

给你一个下标从 0 开始、大小为 n * m 的二维整数矩阵 grid ,定义一个下标从 0 开始、大小为 n * m 的的二维矩阵 p。如果满足以下条件,则称 pgrid乘积矩阵

  • 对于每个元素 p[i][j] ,它的值等于除了 grid[i][j] 外所有元素的乘积。乘积对 12345 取余数。

返回 grid 的乘积矩阵。

 

示例 1:

输入:grid = [[1,2],[3,4]]
输出:[[24,12],[8,6]]
解释:p[0][0] = grid[0][1] * grid[1][0] * grid[1][1] = 2 * 3 * 4 = 24
p[0][1] = grid[0][0] * grid[1][0] * grid[1][1] = 1 * 3 * 4 = 12
p[1][0] = grid[0][0] * grid[0][1] * grid[1][1] = 1 * 2 * 4 = 8
p[1][1] = grid[0][0] * grid[0][1] * grid[1][0] = 1 * 2 * 3 = 6
所以答案是 [[24,12],[8,6]] 。

示例 2:

输入:grid = [[12345],[2],[1]]
输出:[[2],[0],[0]]
解释:p[0][0] = grid[0][1] * grid[0][2] = 2 * 1 = 2
p[0][1] = grid[0][0] * grid[0][2] = 12345 * 1 = 12345. 12345 % 12345 = 0 ,所以 p[0][1] = 0
p[0][2] = grid[0][0] * grid[0][1] = 12345 * 2 = 24690. 24690 % 12345 = 0 ,所以 p[0][2] = 0
所以答案是 [[2],[0],[0]] 。

 

提示:

  • 1 <= n == grid.length <= 105
  • 1 <= m == grid[i].length <= 105
  • 2 <= n * m <= 105
  • 1 <= grid[i][j] <= 109

[Java]基于扩展欧几里得算法求逆元

Problem: 8026. 构造乘积矩阵

[TOC]

思路

本题最简单的解法是前缀后缀积的解法,因为已经有很多题解了,这里就不提了。比赛的时候我一直想基于扩展欧几里得算法求逆元来求解,但是细节没有处理好,比赛没有通过。赛后参考@雪景式大佬的逆元解法,才把细节处理好。

解题方法

由于本题要求每个位置除自己以外的元素乘积,很自然的会想到使用总乘积除以当前位置数字的解法。由于数字太大,需要取模,但是本题的模是12345,不是一个质数,我们在分母的数字是没有办法直接使用费马小定理来求逆元的,也就是$p=12345$时,$a^{p-2}\mod p$是无法求得$a$正确的逆元的。

对于$p=12345$,这种不是质数的,我们可以基于扩展欧几里得算法求逆元,由于扩展欧几里得算法需要互质,而$12345= 35823$, 我们需要对矩阵中是这三个质数倍数的数字做处理,将3,5,823的计数存下来,而对应的数字需要除掉所有的3,5,823的因数,再去做矩阵中所有数字的乘积,用于后面和逆元相乘,得到当前位置的结果。

接着就是如何使用扩展欧几里得算法得到当前矩阵位置数字除掉3,5,823后数值$a$的逆元了。
根据裴蜀定理,如果$a,m$互质,则有:$ax+my = 1$,此时$ax \equiv 1(\mod m)$, 也就是$x$就是$a$的逆元,我们可以辗转相除法求出$a,m$的最大公因数$gcd(a,m)$,在这个过程中对应的系数$x,y$就可以求出来,而$x$就是我们要的逆元。具体可以参考下面ex_gcd和inv两个函数。

当我们求出每个位置的逆元后,就可以求结果了:

  • 对于除了当前位置以外,还有可以同时被3,5,823整除,即被12345整除的因数,直接返回结果0
  • 对于除了当前位置以外,不能被12345整除的因数,则用总乘积乘以当前位置的逆元,还需要乘以剩下所有的3(若有),5(若有),823(若有),最后乘以剩下的3,5,823的幂的部分要使用快速幂。

复杂度

  • 时间复杂度:$O(mn\log U)$,其中$\log U$为扩展欧几里得算法和快速幂的复杂度,这部分对数复杂度取决于矩阵中最大数字的大小,以及3,5,823的最大因数个数。
  • 空间复杂度: $O(1)$

Code

###Java


class Solution {
    int MOD = 12345; //12345 = 3*5*823
    public int[][] constructProductMatrix(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int cnt3 = 0;
        int cnt5 = 0;
        int cnt823 = 0;
        long multiAll = 1;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                int[] tmp = numMod(grid[i][j]);
                cnt3 += tmp[0];
                cnt5 += tmp[1];
                cnt823 += tmp[2];
                multiAll = multiAll * tmp[3] % MOD;
            }
        }
        int[][] res = new int[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                int[] tmp = numMod(grid[i][j]);
                if(cnt3-tmp[0] > 0 && cnt5-tmp[1] > 0 && cnt823-tmp[2] > 0) res[i][j] = 0;
                else{
                    long curRes = multiAll*inv(tmp[3], MOD)%MOD;
                    curRes = curRes*pow(3, cnt3-tmp[0])%MOD;
                    curRes = curRes*pow(5, cnt5-tmp[1])%MOD;
                    curRes = curRes*pow(823, cnt823-tmp[2])%MOD;
                    res[i][j] = (int)curRes;
                }
            }
        }
        return res;
    }
    //计算a^b%MOD
    private long pow(int a, int b){
        long res = 1;
        long a1 = a;
        while(b > 0){
            if((b&1) > 0) res =  (res*a1)%MOD;
            a1 = (a1*a1)%MOD;
            b = b/2;
        }
        return res;
    }
    public int[] numMod(int num){
        int cnt3Cur = 0;
        int cnt5Cur = 0;
        int cnt823Cur = 0;
        while(num%3 == 0){
            num /= 3;
            cnt3Cur++;
        }
        while(num%5 == 0){
            num /= 5;
            cnt5Cur++;
        }
        while(num%823 == 0){
            num /= 823;
            cnt823Cur++;
        }
        return new int[]{cnt3Cur, cnt5Cur, cnt823Cur, num};
    }
    //扩展欧几里得求逆元
    public int[] ex_gcd(int a, int b){
        if(b == 0) return new int[]{a,1,0};
        else {
            int[] res = ex_gcd(b, a%b);
            return new int[]{res[0], res[2], res[1]-(a/b)*res[2]};
        }
    }
    //保证a、m互质的情况下才可以使用
    public int inv(int a, int m){
        int[] res = ex_gcd(a, m);
        if(res[0]  != 1) return -1;
        return (res[1]+m)%m;
    }
}

前后缀分解(Python/Java/C++/C/Go/JS/Rust)

请先完成本题的一维版本238. 除了自身以外数组的乘积

把矩阵平铺成一维数组,就是 238 题了。我们需要算出每个数左边所有数的乘积,以及右边所有数的乘积。

先算出从 $\textit{grid}[i][j]$ 的下一个元素开始,到最后一个元素 $\textit{grid}[n-1][m-1]$ 的乘积,记作 $\textit{suf}[i][j]$。这可以从最后一个数 $\textit{grid}[n-1][m-1]$ 开始,倒着遍历 $\textit{grid}$ 得到。

然后算出从第一个数 $\textit{grid}[0][0]$ 开始,到 $\textit{grid}[i][j]$ 的上一个元素的乘积,记作 $\textit{pre}[i][j]$。这可以从第一行第一列开始,正着遍历得到。

那么

$$
p[i][j] = \textit{pre}[i][j]\cdot \textit{suf}[i][j]
$$

代码实现时,可以先初始化 $p[i][j]=\textit{suf}[i][j]$,然后在计算 $\textit{pre}[i][j]$ 的过程中,把 $\textit{pre}[i][j]$ 乘到 $\textit{p}[i][j]$ 中,就得到了最终答案。这样写的话,$\textit{pre}$ 和 $\textit{suf}$ 可以直接用单个变量表示,无需创建数组。

代码实现时,注意取模。为什么可以在中途取模?原理见 模运算的世界:当加减乘除遇上取模

class Solution:
    def constructProductMatrix(self, grid: List[List[int]]) -> List[List[int]]:
        MOD = 12345
        n, m = len(grid), len(grid[0])
        p = [[0] * m for _ in range(n)]

        suf = 1  # 后缀乘积
        for i in range(n - 1, -1, -1):
            for j in range(m - 1, -1, -1):
                p[i][j] = suf  # p[i][j] 先初始化成后缀乘积
                suf = suf * grid[i][j] % MOD

        pre = 1  # 前缀乘积
        for i, row in enumerate(grid):
            for j, x in enumerate(row):
                p[i][j] = p[i][j] * pre % MOD  # 乘上前缀乘积
                pre = pre * x % MOD

        return p
class Solution {
    public int[][] constructProductMatrix(int[][] grid) {
        final int MOD = 12345;
        int n = grid.length;
        int m = grid[0].length;
        int[][] p = new int[n][m];

        long suf = 1; // 后缀乘积
        for (int i = n - 1; i >= 0; i--) {
            for (int j = m - 1; j >= 0; j--) {
                p[i][j] = (int) suf; // p[i][j] 先初始化成后缀乘积
                suf = suf * grid[i][j] % MOD;
            }
        }

        long pre = 1; // 前缀乘积
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                p[i][j] = (int) (p[i][j] * pre % MOD); // 乘上前缀乘积
                pre = pre * grid[i][j] % MOD;
            }
        }

        return p;
    }
}
class Solution {
public:
    vector<vector<int>> constructProductMatrix(vector<vector<int>>& grid) {
        constexpr int MOD = 12345;
        int n = grid.size(), m = grid[0].size();
        vector p(n, vector<int>(m));

        long long suf = 1; // 后缀乘积
        for (int i = n - 1; i >= 0; i--) {
            for (int j = m - 1; j >= 0; j--) {
                p[i][j] = suf; // p[i][j] 先初始化成后缀乘积
                suf = suf * grid[i][j] % MOD;
            }
        }

        long long pre = 1; // 前缀乘积
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                p[i][j] = p[i][j] * pre % MOD; // 乘上前缀乘积
                pre = pre * grid[i][j] % MOD;
            }
        }

        return p;
    }
};
int** constructProductMatrix(int** grid, int gridSize, int* gridColSize, int* returnSize, int** returnColumnSizes) {
    const int MOD = 12345;
    int n = gridSize, m = gridColSize[0];
    int** p = malloc(n * sizeof(int*));
    *returnSize = n;
    *returnColumnSizes = malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) {
        p[i] = malloc(m * sizeof(int));
        (*returnColumnSizes)[i] = m;
    }

    long long suf = 1; // 后缀乘积
    for (int i = n - 1; i >= 0; i--) {
        for (int j = m - 1; j >= 0; j--) {
            p[i][j] = suf; // p[i][j] 先初始化成后缀乘积
            suf = suf * grid[i][j] % MOD;
        }
    }

    long long pre = 1; // 前缀乘积
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            p[i][j] = p[i][j] * pre % MOD; // 乘上前缀乘积
            pre = pre * grid[i][j] % MOD;
        }
    }

    return p;
}
func constructProductMatrix(grid [][]int) [][]int {
const mod = 12345
n, m := len(grid), len(grid[0])
p := make([][]int, n)
suf := 1 // 后缀乘积
for i := n - 1; i >= 0; i-- {
p[i] = make([]int, m)
for j := m - 1; j >= 0; j-- {
p[i][j] = suf // p[i][j] 先初始化成后缀乘积
suf = suf * grid[i][j] % mod
}
}

pre := 1 // 前缀乘积
for i, row := range grid {
for j, x := range row {
p[i][j] = p[i][j] * pre % mod // 乘上前缀乘积
pre = pre * x % mod
}
}
return p
}
var constructProductMatrix = function(grid) {
    const MOD = 12345;
    const n = grid.length, m = grid[0].length;
    const p = Array.from({ length: n }, () => Array(m).fill(0));

    let suf = 1; // 后缀乘积
    for (let i = n - 1; i >= 0; i--) {
        for (let j = m - 1; j >= 0; j--) {
            p[i][j] = suf; // p[i][j] 先初始化成后缀乘积
            suf = suf * grid[i][j] % MOD;
        }
    }

    let pre = 1; // 前缀乘积
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            p[i][j] = p[i][j] * pre % MOD; // 乘上前缀乘积
            pre = pre * grid[i][j] % MOD;
        }
    }

    return p;
};
impl Solution {
    pub fn construct_product_matrix(grid: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
        const MOD: i64 = 12345;
        let n = grid.len();
        let m = grid[0].len();
        let mut p = vec![vec![0; m]; n];

        let mut suf = 1; // 后缀乘积
        for i in (0..n).rev() {
            for j in (0..m).rev() {
                p[i][j] = suf as i32; // p[i][j] 先初始化成后缀乘积
                suf = suf * grid[i][j] as i64 % MOD;
            }
        }

        let mut pre = 1; // 前缀乘积
        for i in 0..n {
            for j in 0..m {
                p[i][j] = (p[i][j] as i64 * pre % MOD) as i32; // 乘上前缀乘积
                pre = pre * grid[i][j] as i64 % MOD;
            }
        }

        p
    }
}

复杂度分析

  • 时间复杂度:$\mathcal{O}(nm)$,其中 $n$ 和 $m$ 分别是 $\textit{grid}$ 的行数和列数。
  • 空间复杂度:$\mathcal{O}(1)$。返回值不计入。

专题训练

见下面动态规划题单的「专题:前后缀分解」。

分类题单

如何科学刷题?

  1. 滑动窗口与双指针(定长/不定长/单序列/双序列/三指针/分组循环)
  2. 二分算法(二分答案/最小化最大值/最大化最小值/第K小)
  3. 单调栈(基础/矩形面积/贡献法/最小字典序)
  4. 网格图(DFS/BFS/综合应用)
  5. 位运算(基础/性质/拆位/试填/恒等式/思维)
  6. 图论算法(DFS/BFS/拓扑排序/基环树/最短路/最小生成树/网络流)
  7. 动态规划(入门/背包/划分/状态机/区间/状压/数位/数据结构优化/树形/博弈/概率期望)
  8. 常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)
  9. 数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)
  10. 贪心与思维(基本贪心策略/反悔/区间/字典序/数学/思维/脑筋急转弯/构造)
  11. 链表、树与回溯(前后指针/快慢指针/DFS/BFS/直径/LCA)
  12. 字符串(KMP/Z函数/Manacher/字符串哈希/AC自动机/后缀数组/子序列自动机)

我的题解精选(已分类)

欢迎关注 B站@灵茶山艾府

❌