这周没什么人写题解,那就我来写一下吧,不会排版xjb写的,大家xjb看一下就行了

a题
n=int(input())
res=0
while n%10!=0:
    n+=1
    res+=1
print(res)
末尾有0,那么就是整除10,一直自增直到整除10即可

b题  模运算
s=input()
res=t=0
for i in s:
    t=(t*10+int(i))%9
    if t==0:
        res+=1
print(res)
删掉一个后缀,也就是检查所有的前缀形成的数字是否能整除9
讲不太来,可以去lc2575下面看一下

c题 构造
n,k=map(int,input().split())
res=[]
ch=0
while k:
    if k==1:
        res+=[ch]*2
        k-=1
    else:
        l=0;r=n
        while l+1!=r:
            mid=(l+r)//2
            if mid*(mid-1)//2>k:
                r=mid
            else:
                l=mid
        res+=[ch]*l
        k-=l*(l-1)//2
    ch=(ch+1)%26
while len(res)<n:
    res+=[ch]
    ch=(ch+1)%26

print("".join([chr(ord("a")+i) for i in res]))
恰好有k个长度大于1的回文子串,这题我感觉我和大多数人的脑回路都不一样
填还是一样的,按abcd...循环着填就可以了,主要是要构造恰好k个
一个长度为x的字母完全相同子字符串,会有x(x-1)/2个大于1的回文串
直接贪心的每次都填最多的就可以了,每次二分找到这个最大值

d题 贪心
n,k=map(int,input().split())
arr=list(map(int,input().split()))
d=[]
for i in range(1,n):
    d.append(abs(arr[i]-arr[i-1]))
d.sort()
if d[-1]<k:
    print(1)
elif d[-1]==k:
    print(0)
else:
    res=0
    for i in d:
        if i>k:
            res+=(i+k-1)//k-1
    print(res)
先把每相邻两项的差的绝对值拿出来放一起
如果最大值小于k,那么需要一次
如果最大值等于k,那么需要0次
如果最大值大于k,那么把所有大于k的项x取出来
如果恰好是k的倍数,那么中间需要分成x//k份,否则需要分成x//k+1份
合起来写就是(x+k-1)//k份
一个东西分成(x+k-1)//k份,那么就需要切(x+k-1)//k-1刀


e题 调和级数+dp
n=int(input())
a=list(map(int,input().split()))
cnt=[0]*(2*10**5+1)
for i in a:
    cnt[i]+=1
dp={}
res=max(cnt)
for i in range(1,2*10**5+1):
    if cnt[i]:
        for j in range(2*i,2*10**5+1,i):
            if cnt[j]:
                k=j//i
                if (i,k) not in dp:
                    t=1
                else:
                    t=dp[(i,k)]
                res=max(res,t+1)
                dp[(j,k)]=t+1
print(res)
首先需要知道一个知识点,从1到n,每次枚举他们的倍数,每个数一直枚举到大于n停下
总的复杂度是nlogn的,具体可以搜一下调和级数
也就是说如果n是1e5,那么枚举出他们的所有倍数大概需要枚举1e6次,n是1e6,那么就要枚举1e7次
要构成等比数列,一种公比是1,那么我们开头的时候计个数,然后把频率最大值当作初始答案
另一种公比是多少我们不知道,但是肯定大于1的,所以我们从1到2e5,每次枚举他们的倍数,就可以算出这个公比,然后用哈希表+元组dp即可
复杂度是严格的nlogn的

f题 离线回答+树状数组
from collections import deque,defaultdict

class BIT:
    """单点修改,区间和查询"""

    __slots__ = "size", "bit", "tree"

    def __init__(self, n: int):
        self.size = n
        self.bit = n.bit_length()
        self.tree = [0]*(n+1)

    def add(self, index: int, delta: int) -> None:
        # index 必须大于0
        while index <= self.size:
            self.tree[index]+=delta
            index += index & -index

    def _query(self, index: int) -> int: 
        res = 0
        while index > 0:
            res += self.tree[index]
            index -= index & -index
        return res

    def query(self, left: int, right: int) -> int:
        return self._query(right) - self._query(left - 1)

n,q=map(int,input().split())

arr=[0]+list(map(int,input().split()))

d=defaultdict(deque)

for i in range(1,n+1):
    d[arr[i]].append(i)

query=[[] for _ in range(n+1)]

res=[0]*q

bit=BIT(n+5)

for i in range(q):
    l,r=map(int,input().split())
    query[r].append((i,l))

for r in range(1,n+1):
    while r-d[arr[r]][0]>1:
        x=d[arr[r]].popleft()
        bit.add(x,1)
    while query[r]:
        i,l=query[r].pop()
        res[i]=bit.query(l,r)

for i in res:
    if i:
        print("YES")
    else:
        print("NO")
    
给定一个数组,多次询问一个区间[l,r],问该区间是否有长度严格大于2的回文子序列
其实我们只需要求是否有长度为3的回文子序列即可,那么只要有一个数字,出现了两次,且这两次的间隔大于1即可
先预处理出每个数字的出现位置,分别放在一个队列里
然后离线回答,把回答按右端点排序
从小到大遍历下标,对于该下标的数,左侧如果有与他距离大于1且还没出队列的,那么就出队,树状数组单点+1
然后批量回答该右端点的问题,如果区间的和大于0,则就有这样的回文子序列


g题 双指针+树状数组
class BIT:
    """单点修改,区间和查询"""

    __slots__ = "size", "bit", "tree"

    def __init__(self, n: int):
        self.size = n
        self.bit = n.bit_length()
        self.tree = [0]*(n+1)

    def add(self, index: int, delta: int) -> None:
        # index 必须大于0
        while index <= self.size:
            self.tree[index]+=delta
            index += index & -index

    def _query(self, index: int) -> int: 
        res = 0
        while index > 0:
            res += self.tree[index]
            index -= index & -index
        return res

    def query(self, left: int, right: int) -> int:
        return self._query(right) - self._query(left - 1)

sz=10**6+1
n,k=map(int,input().split())
a=list(map(int,input().split()))
bit=BIT(sz+5)
tot=0
for i in range(n):
    tot+=bit.query(a[i]+1,sz+2)
    bit.add(a[i],1)
if tot<k:
    print(0)
    exit()
bit2=BIT(sz+5)
res=0
l=r=0
while r<n:
    tot-=bit._query(a[r]-1)+bit2.query(a[r]+1,sz+2)
    bit.add(a[r],-1)
    while tot<k:
        tot+=bit._query(a[l]-1)+bit2.query(a[l]+1,sz+2)
        bit2.add(a[l],1)
        l+=1
    res+=r-l+1
    r+=1
print(res+1)
求有多少个区间,删除以后剩下的部分逆序数大于等于k
首先求出原区间的逆序数,如果小于k,则无解
然后使用双指针,对左指针左侧部分,和右指针右侧部分各维护一个值域树状数组,设为b1和b2
右指针r右移时 逆序数 = 逆序数 - b1中小于a[r]的个数 - b2中大于a[r]的个数
左指针l右移时 逆序数 = 逆序数 + b1中小于a[l]的个数 + b2中大于a[l]的个数
最后还要加上删除空区间的答案