'''
Author: hhxxrhh 1019962445@qq.com
Date: 2024-01-09 11:45:43
LastEditors: hhxxrhh 1019962445@qq.com
LastEditTime: 2024-02-01 21:13:02
FilePath: \Desktop\a.py
Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
'''
# ## 快速排序 ===========================================(https://blog.csdn.net/flyingluohaipeng/article/details/129134954)
# def quickSort(num,l,r):
#     if(l>=r):
#         return num
#     tmp=num[l]
#     left=l
#     right=r
#     while(l<r):
#         while(num[r]>tmp and l<r):
#             r-=1
#         num[l]=num[r]
#         while(num[l]<tmp and l<r):
#             l+=1
#         num[r]=num[l]
#     num[l]=tmp
#     quickSort(num,left,l-1) 
#     quickSort(num,l+1,right)          
  

# num=[10,20,4,3,1,99,25]
# quickSort(num,0,len(num)-1)
# print(num)

#sorted函数========================================
# a=[[1, 1], [1, 2], [2, 3], [10, 0]]
# b=sorted(a,key=lambda x:x[1],reverse=True)
# dict_={1:10,2:20,5:50,4:40,0:90}

# 生成二维矩阵=========================================
# >>> dp=[[1]*5 for i in range(3)]
# >>> dp
# [[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]

# #全排列问题====================================
# data=[1,2,3]

# def trace(data,index,ans):
#     if(index==len(data)-1):
#         ans.append(data[:])
    
#     for i in range(index,len(data)):
#         data[i],data[index]=data[index],data[i]
#         trace(data,index+1,ans)
#         data[index],data[i]=data[i],data[index]
    
#     return
# ans=[]
# trace(data,0,ans)
# print(ans)


# # ## 二分查找=====================================
# def binary(nums,key):
#     l=0
#     r=len(nums)-1
#     while(l<=r):
#         mid=l+(r-l)//2
#         if(nums[mid]==key):
#             return mid
#         if(nums[mid]>key):
#             r=mid-1
#         else:
#             l=mid+1
#     return -1
# #左边界======================
# def Left_binary(nums,key):
#     l=0
#     r=len(nums)-1
#     while(l<=r):
#         mid=l+(r-l)//2
#         if(nums[mid]>=key):
#             r=mid-1
#         else:
#             l=mid+1
#     if(l>len(nums)-1 or nums[l]!=key):
#         return -1
#     return l
# #右边界
# def Right_binary(nums,key):
#     l=0
#     r=len(nums)-1
#     while(l<=r):
#         mid=l+(r-l)//2
#         if(nums[mid]<=key):
#             l=mid+1
#         else:
#             r=mid-1
#     if(r<0 or nums[r]!=key):
#         return -1
#     return r

# nums=[1,2,3,4,5,8,8,8,8,8,8,10]
# print(Left_binary(nums,8))
# print(Right_binary(nums,8))
# nums=[1,2,3,4,5,8,10]
# print(binary(nums,8))




## LRU算法=============================================================================

# class Node:
#     def __init__(self,val):
#         self.val=val
#         self.next=None
#         self.pre=None
    
# class BiLink:
#     def __init__(self): 
#         self.head=Node(-1)
#         self.tail=Node(-1)
#         self.head.next=self.tail
#         self.tail.pre=self.head
#         self.size=0
    
#     def removeNode(self,node):
#         node.pre.next=node.next
#         node.next.pre=node.pre
#         self.size-=1
    
#     def removeLast(self):
#         self.tail.pre=self.tail.pre.pre
#         self.tail.pre.next=self.tail
#         self.size-=1
    
#     def addFirst(self,node):
#         nextNode=self.head.next
#         self.head.next=node
#         node.pre=self.head
#         node.next=nextNode
#         nextNode.pre=node
#         self.size+=1

#     def printValue(self):
#         node=self.head
#         while(node):
#             print(node.val)
#             node=node.next


# class LRU:
#     def __init__(self,maxSize=5):
#         self.mapNode={}
#         self.link=BiLink()
#         self.maxSize=maxSize
    
#     def put(self,key,value):
#         if(key in self.mapNode):
#             self.get(key,value)
#             return
#         node=Node(value)
#         self.mapNode[key]=node
#         if(self.link.size>=self.maxSize):
#             self.link.removeLast()
#         self.link.addFirst(node)
#         return 
        
        
#     def get(self,key):
#         node=self.mapNode(key)
#         self.link.removeNode(node)
#         self.link.addFirst(node)



#     def printValue(self):
#         self.link.printValue()
        
# lru=LRU()
# lru.put(1,1)
# lru.put(2,2)
# lru.put(3,3)
# lru.put(4,4)
# lru.put(5,5)
# # lru.printValue()
# lru.put(6,6)
# lru.put(60,60)
# lru.put(61,61)
# lru.printValue()
    



# ## node 二叉树的遍历=============================

# class Node:
#     def __init__(self,val):
#         self.val=val
#         self.left=None
#         self.right=None

# def buildTree():
#     root=Node(1)
#     root.left=Node(2)
#     root.right=Node(3)
#     left=root.left
#     right=root.right
#     left.left=Node(4)
#     left.right=Node(5)

#     return root

# def printTree(root):
#     queue=[root]
#     while(len(queue)>0):
#         tmp=queue
#         queue=[]
#         for i in range(len(tmp)):
#             print(tmp[i].val)
#             if(tmp[i].left is not None):
#                 queue.append(tmp[i].left)
#             if(tmp[i].right is not None):
#                 queue.append(tmp[i].right)
#     return

# def inOrder(root):
#     if(root is None):return
#     print(root.val)
#     inOrder(root.left)
#     inOrder(root.right)
#     return

# root=buildTree()
# inOrder(root)
        
# #最长回文子串(连续) 动态规划=================================================
# def find(data):
#     ans=1
#     dp=[[0]*len(data) for i in range(len(data))]
#     for i in range(len(data)):
#         dp[i][i]=1
    
#     for i in range(len(data)-1,-1,-1):
#         for j in range(i+1,len(data)):
#             if(data[i]==data[j] and j-i<=1):
#                 dp[i][j]=1     
#             elif(data[i]==data[j] and dp[i+1][j-1]==1):
#                 dp[i][j]=1
#             if(dp[i][j]==1 and j-i+1>ans):
#                 ans=j-i+1
#     return ans
# data="aababaac"
# print(find(data))




# ## k-means=================================================================================
# import numpy as np
# class Kmeans:
#     def __init__(self, k=2, tolerance=0.01, max_iter=300):
#         self.k = k
#         self.tol = tolerance
#         self.max_iter = max_iter
#         self.classifications = None
#         self.centroids = None

#     def fit(self, data):
#         """
#         :param data: numpy数组,约定shape为:(数据数量,数据维度)
#         :type data: numpy.ndarray
#         """
         
#         # 初始化聚类中心(维度:k个 * features种数)
#         self.centroids = np.zeros([self.k, data.shape[1]])
#         for i in range(self.k):
#             self.centroids[i] = data[i]

#         for i in range(self.max_iter):
#             # 清空聚类列表
#             self.classifications = [[] for i in range(self.k)]
#             # 对每个点与聚类中心进行距离计算
#             for feature_set in data:
#                 # 预测分类
#                 classification = self.predict(feature_set)
#                 # 加入类别
#                 self.classifications[classification].append(feature_set)

#             # 记录前一次的结果
#             prev_centroids = np.ndarray.copy(self.centroids)

#             # 更新中心
#             for classification in range(self.k):
#                 self.centroids[classification] = np.average(self.classifications[classification], axis=0) #axis=0 保留行 1:保留列

#             # 检测相邻两次中心的变化情况
#             for c in range(self.k):
#                 if np.sum(np.abs(prev_centroids[c] - self.centroids[c])) > self.tol:
#                     break

#             # 如果都满足条件(上面循环没break),则返回
#             else:
#                 return

#     def predict(self, data):
#         # 距离
#         distances = np.sum(np.abs(data - self.centroids),axis=1)
#         print(distances)
#         # 最小距离索引
#         return distances.argmin()
    
# data=[[1,2,3,4,5],[6,7,8,9,0],[1,2,3,4,50],[1,1,1,1,1]]
# data=np.array(data)
# algo=Kmeans()
# algo.fit(data)
# print(algo.predict(data[0]))

# ##union-find 算法


# ##attention

# # ## 两个序列的中位数//寻找两个序列的第k小的数 log复杂度  有序数组====================================
# def getAnswer(start1,end1,num1,start2,end2,num2,k):
#     len1=end1-start1+1
#     len2=end2-start2+1
#     if(len1==0):
#         return num2[start2+k-1]
#     elif(len2==0):
#         return num1[start1+k-1]
#     if(k==1):
#         return min(num1[start1],num2[start2])
    
#     p1=start1+min(k//2,len1)-1
#     p2=start2+min(k//2,len2)-1
#     if(num1[p1]<num2[p2]):
#         return getAnswer(p1+1,end1,num1,start2,end2,num2,k-(p1-start1+1))
#     else:
#         return getAnswer(start1,end1,num1,p2+1,end2,num2,k-(p2-start2+1))

# a=[1,2,5,10,19,20]
# b=[3,4,5,67,100,200]
# left=(len(a)+len(b)+1)//2
# right=(len(a)+len(b)+2)//2
# print((getAnswer(0,len(a)-1,a,0,len(b)-1,b,left)+getAnswer(0,len(a)-1,a,0,len(b)-1,b,right))/2)


# #数据流中的中位数(堆实现)===============================================================
# from heapq import heappush,heappushpop,heappop

# class Solution:
#     def __init__(self):
#         self.maxHeap=[]
#         self.minHeap=[]
    
#     def insert(self,num):
#         if(len(self.maxHeap)==len(self.minHeap)):
#             heappush(self.maxHeap, -heappushpop(self.minHeap,num))
#         else:
#             heappush(self.minHeap,-heappushpop(self.maxHeap,-num))

#     def getMid(self):
#         if(len(self.maxHeap)==len(self.minHeap)):
#             return (heappop(self.minHeap)-heappop(self.maxHeap))/2
#         else:
#             return -heappop(self.maxHeap)

# tmp=Solution()
# for i in range(9):
#     tmp.insert(i)
# print(tmp.maxHeap,tmp.minHeap)
# print(tmp.getMid())
#满二叉树  赋值邻居节点  时间复杂度o(n) 空间复杂度O(1)===========================================
# # //               1
# # //          2      ->         3
# # // 4      ->   5    ->    6  ->  7

# # struct TreeNode {
# #   int val;
# #   TreeNode left;
# #   TreeNode right;
# #   TreeNode sibling;
# # };


# def solution(root):
#     tmp=root
#     while(tmp):
#       nextTmp=tmp.left
#       while(tmp):
#         tmp.left.sibling=tmp.right
#         if(tmp.sibling):
#           tmp.right.sibling=tmp.sibling.left
#         tmp=tmp.sibling
#       tmp=nextTmp
 

 

# //题目:设计一个数据结构,实现方法set(i,val)/get(i)/setall(val),三个方法的时间复杂度都是O(1)

# class solution:
#      def __init__(self):
# 		self.setall=-1
#         self.dict={}
# 		self.dictValue={}
# 		self.maxTime=-1
#         self.allValue=-1

    
#     def set(self,i,val):
# 		self.dict[i]=self.maxTime
#         self.maxTime+=1
#         self.dictValue[i]=val
    
#     def setall(self,val):
# 		self.setall=self.maxTime+1
#         self.maxTime+=1
#         self.allValue=val
          
            
#     def get(self,i):
# 		if(self.dict[i]>self.setall):
# 			return self.dictValue[i]
#         else:
# 			return self.allValue