解决leetcode第3901题好子序列查询

3901.好子序列查询

难度:困难

问题描述:

给你一个长度为n的整数数组nums和一个整数p。

如果nums的一个非空子序列满足以下条件,则称其为好子序列:

其长度严格小于n。

其所有元素的最大公约数(GCD)恰好等于p。

另给定一个长度为q的二维整数数组queries,其中queriesi=indi,vali表示你需要将numsindi更新为vali。

在每次查询更新后,判断当前数组中是否存在任意一个好子序列。

返回一个整数,表示在多少次查询之后,数组中存在好子序列。

子序列是指通过删除原序列中的某些元素或不删除任何元素,并且不改变剩余元素相对顺序后得到的序列。

gcd(a,b)表示a和b的最大公约数。

示例1:

输入:nums=4,8,12,16,p=2,queries=\[0,3,2,6]

输出:1

解释:

i indi,vali 操作 更新后的nums 是否存在好子序列

0 0,3 将nums0更新为3 3,8,12,16 否,因为不存在最大公约数恰好为p=2的子序列

1 2,6 将nums2更新为6 3,8,6,16 是,子序列8,6的最大公约数恰好为p=2

因此,答案是1。

示例2:

输入:nums=4,5,7,8,p=3,queries=\[0,6,1,9,2,3]

输出:2

解释:

i indi,vali 操作 更新后的nums 是否存在好子序列

0 0,6 将nums0更新为6 6,5,7,8 否,因为不存在最大公约数恰好为p=3的子序列

1 1,9 将nums1更新为9 6,9,7,8 是,子序列6,9的最大公约数恰好为p=3

2 2,3 将nums2更新为3 6,9,3,8 是,子序列6,9,3的最大公约数恰好为p=3

因此,答案是2。

示例3:

输入:nums=5,7,9,p=2,queries=\[1,4,2,8]

输出:0

解释:

i indi,vali 操作 更新后的nums 是否存在好子序列

0 1,4 将nums1更新为4 5,4,9 否,因为不存在最大公约数恰好为p=2的子序列

1 2,8 将nums2更新为8 5,4,8 否,因为不存在最大公约数恰好为p=2的子序列

因此,答案是0。

提示:

2<=n==nums.length<=5*104

1<=numsi<=5*104

1<=queries.length<=5*104

queriesi=indi,vali

1<=vali,p<=5*104

0<=indi<=n-1

问题分析:

为解决本问题,第一个要解决的是如何求出多个整数的最大公约数,为此设计函数my_gcd(a),其功能是对于一个列表a,求出其中所有元素的最大公约数并返回;其次是判断一个序列是否为一个好序列,为此设计函数check_a_good_sub_array(a,p),用于判断一个列表a是否存在有一个子序列,其最大公约数为p,如果存在,则a是好序列,返回True,否则返回False,在具体处理的时候,不需要把a的所有子序列都找出来,而是把a中所有能被p整除的元素按顺序找出,并重新生成一个列表,然后对这个列表进行处理,这样会签单得多;最后在主程序中按queries列表中的操作依次进行处理,统计好子序列数并输出,问题得到解决。

程序如下:

python 复制代码
from math import gcd
#计算一个列表中所有元素的最大公约数并返回
def my_gcd(a):
    n=len(a)
    if n==2:
        return gcd(a[0],a[1])
    else:
        return gcd(a[0],my_gcd(a[1:n]))

#判断一个列表是否为一个好序列,如果是返回True,否则返回False
def check_a_good_sub_array(a,p):
    n=len(a)
    t=[]
    for i in a:
        if i%p==0:
            t.append(i)
    m=len(t)
    if m<2:
        return False,[]
    else:
        for i in range(0,m-1):
            for j in range(i+2,m+1):
                b=t[i:j]
                c=my_gcd(b)
                if c==1:
                    break
                elif c==p and len(b)!=n:
                    return True,b
                else:
                    continue
        else:
            return False,[]

#主程序
nums=eval(input('pls input nums='))
p=int(input('pls input p='))
queries=eval(input('pls input queries='))
n=len(nums)
c=0
for i in queries:
    print('操作:',i,end='  ')
    nums[i[0]]=i[1]
    print('操作后的nums为:',nums,end='  ' )
    flag,t=check_a_good_sub_array(nums,p)
    if flag:
        print(f'是,子序列({t})的最大公约数恰好为p={p}的子序列')
        c+=1
    else:
        print(f'否,因为不存在最大公约数为p={p}的长度严格小于{n}子序列')
print(f'经过多次查询之后,存在的好子序列共有{c}个')

运行实例一

pls input nums=3,5,7,1

pls input p=3

pls input queries=\[2,9,1,6]

操作: 2, 9 操作后的nums为: 3, 5, 9, 1 是,子序列(3, 9)的最大公约数恰好为p=3的子序列

操作: 1, 6 操作后的nums为: 3, 6, 9, 1 是,子序列(3, 6)的最大公约数恰好为p=3的子序列

经过多次查询之后,存在的好子序列共有2个

运行实例二

pls input nums=2,3,5,6

pls input p=2

pls input queries=\[0,1,2,4]

操作: 0, 1 操作后的nums为: 1, 3, 5, 6 否,因为不存在最大公约数为p=2的子序列

操作: 2, 4 操作后的nums为: 1, 3, 4, 6 是,子序列(4, 6)的最大公约数恰好为p=2的子序列

经过多次查询之后,存在的好子序列共有1个

运行实例三

pls input nums=2,3

pls input p=3

pls input queries=\[0,6]

操作: 0, 6 操作后的nums为: 6, 3 否,因为不存在最大公约数为p=3的长度严格小于2子序列

经过多次查询之后,存在的好子序列共有0个

相关推荐
信誓旦旦的程序猿20 小时前
【Python量化实战宝典 #22】涨跌停、连板情绪手册:情绪指标构建(Python 可跑)
python·1024程序员节·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
gCode Teacher 格码致知20 小时前
Pandas教学-21:subplots的使用
python·pandas·1024程序员节
2601_9679801120 小时前
Python开发的顶级开源项目全景图:2025-2026年生态概览
python·机器学习·开源项目·数据科学·生态概览
小郎君65821 小时前
MPTT树复选框的半选状态:一棵百万节点树从递归到计数器,再到区间覆盖
算法
酌沧21 小时前
MemT让记忆成为模型内生能力
jvm·人工智能·算法
benchmark_cc21 小时前
量化开发中,什么时候应该停止手动下载股票数据?
python·数据分析·pandas·量化交易·1024程序员节·股票数据·quantdash
泡茶喝茶写代码21 小时前
A股量化策略回测实战:从行情数据到绩效评估(第 15 篇):新高新低策略
python·1024程序员节·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
hold?fish:palm21 小时前
40 二叉树的直径
c++·leetcode
全栈练习生1 天前
Jev 决策模型
python·ai·1024程序员节
LMT流氓兔1 天前
第五单元——第十二课:把脚本整理成项目
java·数据库·python·langchain·1024程序员节