爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      【动态规划】【滑动窗口】【C++算法】 629K 个逆序对数组

      首页 知识中心 软件开发 文章详情页

      【动态规划】【滑动窗口】【C++算法】 629K 个逆序对数组

      2025-02-18 07:28:59 阅读次数:17

      amp,class,const,int,iNum,return,vector

      LeetCode629: K 个逆序对数组

      逆序对的定义如下:对于数组 nums 的第 i 个和第 j 个元素,如果满足 0 <= i < j < nums.length 且 nums[i] > nums[j],则其为一个逆序对;否则不是。
      给你两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个 逆序对 的不同的数组的个数。由于答案可能很大,只需要返回对 109 + 7 取余的结果。
      示例 1:
      输入:n = 3, k = 0
      输出:1
      解释:
      只有数组 [1,2,3] 包含了从1到3的整数并且正好拥有 0 个逆序对。
      示例 2:
      输入:n = 3, k = 1
      输出:2
      解释:
      数组 [1,3,2] 和 [2,1,3] 都有 1 个逆序对。
      提示:
      1 <= n <= 1000
      0 <= k <= 1000

      动态规划

      ** 空间复杂度**: O(n)
      时间复杂度😮(n2)
      动态规划的状态表示:pre[i]表示1到j-1的排列中,逆数对数量为i的数量。dp[i]表示1到j的排列中,逆数对的数量。 i 取值范围[0,1000]
      动态规划的转移方程: 假定某个1到j-1 的排列,逆数对为x。插入j后,除j外的顺序不边,也就是除j外,不会产生新的逆数对。当然也不会减少逆数对。那如果将j插入到最后,逆序数不变。插入到倒数第一之前,逆数对+1。。。插入到最前面,逆序对+j-1。换过说法:
      dp[i] = Sum ( i − j , i ] k ^{k}_{(i-j,i]} (i−j,i]k​pre[k]。 可以利用滑动窗口求和。
      动态规划的初始状态: pre[0]=0
      动态规划的填表顺序: j 从小到大,i从小到大。
      动态规划的返回值:pre[k]

      代码

      使用到的类库

      template<int MOD = 1000000007>
      class C1097Int
      {
      public:
      	C1097Int(long long llData = 0) :m_iData(llData% MOD)
      	{
      
      	}
      	C1097Int  operator+(const C1097Int& o)const
      	{
      		return C1097Int(((long long)m_iData + o.m_iData) % MOD);
      	}
      	C1097Int& operator+=(const C1097Int& o)
      	{
      		m_iData = ((long long)m_iData + o.m_iData) % MOD;
      		return *this;
      	}
      	C1097Int& operator-=(const C1097Int& o)
      	{
      		m_iData = (m_iData + MOD - o.m_iData) % MOD;
      		return *this;
      	}
      	C1097Int  operator-(const C1097Int& o)
      	{
      		return C1097Int((m_iData + MOD - o.m_iData) % MOD);
      	}
      	C1097Int  operator*(const C1097Int& o)const
      	{
      		return((long long)m_iData * o.m_iData) % MOD;
      	}
      	C1097Int& operator*=(const C1097Int& o)
      	{
      		m_iData = ((long long)m_iData * o.m_iData) % MOD;
      		return *this;
      	}
      	bool operator<(const C1097Int& o)const
      	{
      		return m_iData < o.m_iData;
      	}
      	C1097Int pow(long long n)const
      	{
      		C1097Int iRet = 1, iCur = *this;
      		while (n)
      		{
      			if (n & 1)
      			{
      				iRet *= iCur;
      			}
      			iCur *= iCur;
      			n >>= 1;
      		}
      		return iRet;
      	}
      	C1097Int PowNegative1()const
      	{
      		return pow(MOD - 2);
      	}
      	int ToInt()const
      	{
      		return m_iData;
      	}
      private:
      	int m_iData = 0;;
      };
      

      核心代码

      class Solution {
      public:
      	int kInversePairs(int n, int k) {
      		vector<C1097Int<>> pre(1001) ;
      		pre[0] = 1;
      		for (int j = 2; j <= n; j++)
      		{
      			vector<C1097Int<>> dp(1001);
      			C1097Int<> iSum = 0;
      			for (int i = 0; i < pre.size(); i++)
      			{
      				iSum += pre[i];
      				if (i - j >= 0)
      				{
      					iSum -= pre[i - j];
      				}
      				dp[i] = iSum;
      			}
      			pre.swap(dp);
      		}
      		return pre[k].ToInt();
      	}
      };
      

      测试用例

      template<class T>
      void Assert(const T& t1, const T& t2)
      {
      	assert(t1 == t2);
      }
      
      template<class T>
      void Assert(const vector<T>& v1, const vector<T>& v2)
      {
      	if (v1.size() != v2.size())
      	{
      		assert(false);
      		return;
      	}
      	for (int i = 0; i < v1.size(); i++)
      	{
      		Assert(v1[i], v2[i]);
      	}
      }
      
      
      int main()
      {
      	int n,k;
      	{
      		Solution sln;
      		n = 3, k = 0;
      		auto res = sln.kInversePairs(n, k);
      		Assert(1, res);
      	}
      	{
      		Solution sln;
      		n = 3, k = 1;
      		auto res = sln.kInversePairs(n, k);
      		Assert(2, res);
      	}
      
      	{
      		Solution sln;
      		n = 1000, k = 1000;
      		auto res = sln.kInversePairs(n, k);
      		Assert(663677020, res);
      	}
      }
      

      2023年1月版

      class CBigMath
      {
      public:
      static void AddAssignment(int* dst, const int& iSrc)
      {
      *dst = (*dst + iSrc) % s_iMod;
      }

       static void AddAssignment(int* dst, const int& iSrc, const int& iSrc1)
       {
      	 *dst = (*dst + iSrc) % s_iMod;
      	 *dst = (*dst + iSrc1) % s_iMod;
       }
      
       static void AddAssignment(int* dst, const int& iSrc, const int& iSrc1, const int& iSrc2)
       {
      	 *dst = (*dst + iSrc) % s_iMod;
      	 *dst = (*dst + iSrc1) % s_iMod;
      	 *dst = (*dst + iSrc2) % s_iMod;
       }
      
       static void SubAssignment(int* dst, const int& iSrc)
       {
      	 *dst = (s_iMod - iSrc + *dst) % s_iMod;
       }
       static int Add(const int& iAdd1, const int& iAdd2)
       {
      	 return (iAdd1 + iAdd2) % s_iMod;
       }
       static int Mul(const int& i1, const int& i2)
       {
      	 return((long long)i1 *i2) % s_iMod;
       }
      

      private:
      static const int s_iMod = 1000000007;
      };

      class Solution {
      public:
      int kInversePairs(int n, int k) {
      vector preDp(k + 1);
      preDp[0] = 1;
      for (int i = 2; i <= n; i++)
      {
      vector dp(k+1 );
      for (int j = 0; j < dp.size(); j++)
      {
      if (j < preDp.size())
      {
      CBigMath::AddAssignment(&dp[j], preDp[j]);
      }
      if (j > 0)
      {
      CBigMath::AddAssignment(&dp[j], dp[j - 1]);
      }
      if ( j - i >= 0)
      {
      int iMod = 1000000007;
      CBigMath::AddAssignment(&dp[j], iMod - preDp[j - i]);
      }
      }
      preDp.swap(dp);
      }
      return k >= preDp.size() ? 0 : preDp[k];
      }
      };

      2023年6月

      using namespace std;

      template
      void OutToConsoleInner(const vector& vec,const string& strSep = " ")
      {
      for (int i = 0; i < vec.size(); i++)
      {
      if (0 != i%25)
      {
      std::cout << strSep.c_str();
      }
      std::cout << setw(3) << setfill(’ ') << vec[i];
      if (0 == (i+1) % 25)
      {
      std::cout << std::endl;
      }
      else if (0 == (i + 1) % 5)
      {
      std::cout << strSep.c_str();
      }
      }
      }

      class CConsole
      {
      public :

      template<class T>
      static void Out(const vector<T>& vec, const string& strColSep = " ", const string& strRowSep = "\r\n")
      {
      	OutToConsoleInner(vec, strColSep);
      	std::cout << strRowSep.c_str();
      }
      
      template<class T>
      static void Out(const vector<vector<T>>& matrix, const string& strColSep = " ", const string& strRowSep = "\r\n")
      {
      	for (int i = 0; i < matrix.size(); i++)
      	{
      		OutToConsoleInner(matrix[i], strColSep);
      		std::cout << strRowSep.c_str();
      	}
      }
      
      template<class T>
      static void Out(const std::map<T, std::vector<int> >& mTopPointToPoints, const string& strColSep = " ", const string& strRowSep = "\r\n")
      {
      	for (auto kv : mTopPointToPoints)
      	{
      		std::cout << kv.first << ":";
      		OutToConsoleInner(kv.second, strColSep);
      		std::cout << strRowSep.c_str();
      	}
      }
      
      
      static void Out(const  std::string& t, const string& strColSep = " ", const string& strRowSep = "\r\n")
      {
      	std::cout << t.c_str() << strColSep.c_str();
      }
      
      template<class T  >
      static void Out(const T& t, const string& strColSep = " ", const string& strRowSep = "\r\n")
      {
      	std::cout << t << strColSep.c_str();
      }
      

      };

      void GenetateSum(vector& sums, const vector& nums)
      {
      sums.push_back(0);
      for (int i = 0; i < nums.size(); i++)
      {
      sums.push_back(nums[i] + sums[i]);
      }
      }

      //[iBegin,iEnd]之和
      long long Total(int iBegin,int iEnd)
      {
      return (long long)(iBegin + iEnd)*(iEnd - iBegin + 1) / 2;
      }

      class CLadderhlp
      {
      public:
      CLadderhlp( int ladders)
      {
      m_uLadderNum = ladders;
      }
      void AddNeedBick(int iNeedBick)
      {
      if (0 == m_uLadderNum)
      {
      return;
      }
      if (m_ladders.size() < m_uLadderNum)
      {
      m_ladders.push(iNeedBick);
      m_iEaqualBicks += iNeedBick;
      return;
      }
      int iTop = m_();
      if (iTop >= iNeedBick)
      {
      return;
      }
      m_iEaqualBicks -= iTop;
      m_iEaqualBicks += iNeedBick;
      m_ladders.pop();
      m_ladders.push(iNeedBick);
      }
      std::priority_queue<int,vector,std::greater > m_ladders;
      unsigned int m_uLadderNum;
      long long m_iEaqualBicks = 0;
      };

      struct CPeo
      {
      CPeo(string strName, CPeo* pParent=nullptr)
      {
      m_strName = strName;
      m_pParent = pParent;
      }
      string m_strName;
      vector<CPeo*> m_childs;
      CPeo* m_pParent = nullptr;
      };

      class CNeighborTable
      {
      public:
      void Init(const vector<vector>& edges)
      {

       }
       vector<vector<int>> m_vTable;
      

      };

      //通过 x &= (x-1)实现
      int bitcount(unsigned x) {
      int countx = 0;
      while (x) {
      countx++;
      x &= (x - 1);
      }
      return countx;
      }

      int bitcount(unsigned long long x) {
      int countx = 0;
      while (x) {
      countx++;
      x &= (x - 1);
      }
      return countx;
      }

      class CRange
      {
      public:
      template
      CRange(const T& v)
      {
      m_iBegin = 0;
      m_iEnd = v.size();
      }
      bool In(int iIndex)
      {
      return (iIndex >= m_iBegin) && (iIndex < m_iEnd);
      }
      const int End()
      {
      return m_iEnd;
      }
      protected:
      int m_iBegin;
      int m_iEnd;
      };

      template
      class CTrie
      {
      public:
      CTrie() :m_vPChilds(iTypeNum)
      {

       }
       template<class IT>
       void Add(IT begin, IT end)
       {
      	 CTrie<iTypeNum, cBegin> * pNode = this;
      	 for (; begin != end; ++begin)
      	 {
      		 pNode = pNode->AddChar(*begin).get();
      	 }
       }
       template<class IT>
       bool Search(IT begin, IT end)
       {
      	 if (begin == end)
      	 {
      		 return true;
      	 }
      
      	 if ('.' == *begin)
      	 {
      		 for (auto& ptr : m_vPChilds)
      		 {
      			 if (!ptr)
      			 {
      				 continue;
      			 }
      			 if (ptr->Search(begin + 1, end))
      			 {
      				 return true;
      			 }
      		 }
      	 }
      
      	 auto ptr = GetChild(*begin);
      	 if (nullptr == ptr)
      	 {
      		 return false;
      	 }
      	 return ptr->Search(begin + 1, end);
       }
      

      protected:
      std::shared_ptr AddChar(char ch)
      {
      if ((ch < cBegin) || (ch >= cBegin + iTypeNum))
      {
      return nullptr;
      }
      const int index = ch - cBegin;
      auto ptr = m_vPChilds[index];
      if (!ptr)
      {
      m_vPChilds[index] = std::make_shared<CTrie<iTypeNum, cBegin>>();
      }
      return m_vPChilds[index];
      }
      std::shared_ptr GetChild(char ch)const
      {
      if ((ch < cBegin) || (ch >= cBegin + iTypeNum))
      {
      return nullptr;
      }
      return m_vPChilds[ch - cBegin];
      }
      std::vector<std::shared_ptr> m_vPChilds;
      };

      class CWords
      {
      public:
      void Add(const string& word)
      {
      m_strStrs.insert(word);
      }
      bool Search(const string& word)
      {
      return Search(m_strStrs.begin(), m_strStrs.end(), 0, word.length(), word);
      }
      protected:
      bool Search(std::set::const_iterator begin, std::set::const_iterator end, int iStrBegin, int iStrEnd, const string& str)
      {
      int i = iStrBegin;
      for (; (i < iStrEnd) && (str[i] != ‘.’); i++);
      auto it = std::equal_range(begin, end, str, [&iStrBegin, &i](const string& s, const string& sFind)
      {
      return s.substr(iStrBegin, i - iStrBegin) < sFind.substr(iStrBegin, i - iStrBegin);
      });
      if (i == iStrBegin)
      {
      it.first = begin;
      it.second = end;
      }
      if (it.first == it.second)
      {
      return false;
      }
      if (i == iStrEnd)
      {
      return true;
      }
      if (i + 1 == iStrEnd)
      {
      return true;
      }
      string tmp = str;
      for (char ch = ‘a’; ch <= ‘z’; ch++)
      {
      tmp[i] = ch;
      auto ij = std::equal_range(it.first, it.second, tmp, [&ch, &i](const string& s, const string& sFind)
      {
      return s[i] < sFind[i];
      });
      if (ij.first == ij.second)
      {
      continue;
      }

      		 if (Search(ij.first, ij.second, i + 1, iStrEnd, str))
      		 {
      			 return true;
      		 }
      	 }
      	 return false;
       }
      
       std::set<string> m_strStrs;
      

      };
      class WordDictionary {
      public:
      WordDictionary() {
      for (int i = 0; i < 26; i++)
      {
      m_str[i] = std::make_unique();
      }
      }

       void addWord(string word) {
      	 m_str[word.length()]->Add(word);
       }
      
       bool search(string word) {
      	 return m_str[word.length()]->Search(word);
       }
       std::unique_ptr<CWords> m_str[26];
      

      };

      template
      class C1097Int
      {
      public:
      C1097Int(long long llData = 0) :m_iData(llData%MOD)
      {

       }
       C1097Int  operator+(const C1097Int& o)const
       {
      	 return C1097Int(((long long)m_iData + o.m_iData) % MOD);
       }
       C1097Int&  operator+=(const C1097Int& o)
       {
      	 m_iData = ((long long)m_iData + o.m_iData) % MOD;
      	 return *this;
       }
       C1097Int&  operator-=(const C1097Int& o)
       {
      	 m_iData = (m_iData + MOD - o.m_iData) % MOD;
      	 return *this;
       }
       C1097Int  operator-(const C1097Int& o)
       {
      	 return C1097Int((m_iData + MOD - o.m_iData) % MOD);
       }
       C1097Int  operator*(const C1097Int& o)const
       {
      	 return((long long)m_iData *o.m_iData) % MOD;
       }
       C1097Int&  operator*=(const C1097Int& o)
       {
      	 m_iData = ((long long)m_iData *o.m_iData) % MOD;
      	 return *this;
       }
       bool operator<(const C1097Int& o)const
       {
      	 return m_iData < o.m_iData;
       }
       C1097Int pow( int n)const
       {
      	 C1097Int iRet = 1, iCur = *this;
      	while (n)
      	{
      		if (n & 1)
      		{
      			iRet *= iCur;
      		}
      		iCur *= iCur;
      		n >>= 1;
      	}
      	return iRet;
       }
       C1097Int PowNegative1()const
       {
      	 return pow(MOD - 2);
       }
       int ToInt()const
       {
      	 return m_iData;
       }
      

      private:
      int m_iData = 0;;
      };

      template
      int operator+(int iData, const C1097Int& int1097)
      {
      int iRet = int1097.operator+(C1097Int(iData)).ToInt();
      return iRet;
      }

      template
      int& operator+=(int& iData, const C1097Int& int1097)
      {
      iData = int1097.operator+(C1097Int(iData)).ToInt();
      return iData;
      }

      template
      int operator*(int iData, const C1097Int& int1097)
      {
      int iRet = int1097.operator*(C1097Int(iData)).ToInt();
      return iRet;
      }

      template
      int& operator*=(int& iData, const C1097Int& int1097)
      {
      iData = int1097.operator*(C1097Int(iData)).ToInt();
      return iData;
      }

      template
      void MinSelf(T* seft, const T& other)
      {
      *seft = min(*seft, other);
      }

      template
      void MaxSelf(T* seft, const T& other)
      {
      *seft = max(*seft, other);
      }

      int GetNotRepeateNum(int len, int iHasSel)
      {
      if (0 == len)
      {
      return 1;
      }
      if ((0 == iHasSel) && (1 == len))
      {
      return 10;
      }
      int iRet = 1;
      if (iHasSel > 0)
      {
      for (int tmp = 10 - iHasSel; (tmp >= 2)&& len ; tmp–,len–)
      {
      iRet *= tmp;
      }
      }
      else
      {
      iRet *= 9;
      len–;
      for (int tmp=9; (tmp>=2)&&len; len–,tmp–)
      {
      iRet *= tmp;
      }
      }
      return iRet;
      }

      int GCD(int n1, int n2)
      {
      int t1 = min(n1, n2);
      int t2 = max(n1, n2);
      if (0 == t1)
      {
      return t2;
      }
      return GCD(t2%t1, t1);
      }

      void CreateMaskVector(vector& v,const int* const p,int n )
      {
      const int iMaxMaskNum = 1 << n;
      v.resize(iMaxMaskNum);
      for (int i = 0; i < n; i++)
      {
      v[1 << i] = p[i];
      }
      for (int mask = 1; mask < iMaxMaskNum ; mask++)
      {
      const int iSubMask = mask&(-mask);
      v[mask] = v[iSubMask] + v[mask-iSubMask];
      }
      }

      class CMaxLineTree
      {
      public:
      CMaxLineTree(int iArrSize) :m_iArrSize(iArrSize), m_vData(iArrSize * 4)
      {

       }
       //iIndex 从0开始
       void Modify( int iIndex, int iValue)
       {
      	 Modify(1, 1, m_iArrSize, iIndex + 1, iValue);
       }
       //iNeedQueryLeft iNeedQueryRight 从0开始
       int Query(const int iNeedQueryLeft, const int iNeedQueryRight)
       {
      	 return Query(1, 1, m_iArrSize, iNeedQueryLeft + 1, iNeedQueryRight + 1);
       }
      

      protected:
      int Query(const int iTreeNodeIndex, const int iRecordLeft, const int iRecordRight, const int iNeedQueryLeft, const int iNeedQueryRight)
      {
      if ((iNeedQueryLeft <= iRecordLeft) && (iNeedQueryRight >= iRecordRight))
      {
      return m_vData[iTreeNodeIndex];
      }
      const int iMid = (iRecordLeft + iRecordRight) / 2;
      int iRet = 0;
      if (iNeedQueryLeft <= iMid)
      {
      iRet = Query(iTreeNodeIndex * 2, iRecordLeft, iMid, iNeedQueryLeft, iNeedQueryRight);
      }
      if (iNeedQueryRight > iMid)
      {
      iRet = max(iRet, Query(iTreeNodeIndex * 2 + 1, iMid + 1, iRecordRight, iNeedQueryLeft, iNeedQueryRight));
      }
      return iRet;
      }
      void Modify(int iTreeNodeIndex, int iLeft, int iRight, int iIndex, int iValue)
      {
      if (iLeft == iRight)
      {
      m_vData[iTreeNodeIndex] = max(m_vData[iTreeNodeIndex],iValue);
      return;
      }
      const int iMid = (iLeft + iRight) / 2;
      if (iIndex <= iMid)
      {
      Modify(iTreeNodeIndex * 2, iLeft, iMid, iIndex, iValue);
      }
      else
      {
      Modify(iTreeNodeIndex * 2 + 1, iMid + 1, iRight, iIndex, iValue);
      }
      m_vData[iTreeNodeIndex] = max(m_vData[iTreeNodeIndex * 2], m_vData[iTreeNodeIndex * 2 + 1]);
      }
      const int m_iArrSize;
      std::vector m_vData;
      };

      class CMaxLineTreeMap
      {
      public:
      CMaxLineTreeMap(int iArrSize) :m_iArrSize(iArrSize)
      {

       }
       //iIndex 从0开始
       void Modify(int iIndex, int iValue)
       {
      	 Modify(1, 1, m_iArrSize, iIndex + 1, iValue);
       }
       //iNeedQueryLeft iNeedQueryRight 从0开始
       int Query(const int iNeedQueryLeft, const int iNeedQueryRight)
       {
      	 return Query(1, 1, m_iArrSize, iNeedQueryLeft + 1, iNeedQueryRight + 1);
       }
      

      protected:
      int Query(const int iTreeNodeIndex, const int iRecordLeft, const int iRecordRight, const int iNeedQueryLeft, const int iNeedQueryRight)
      {
      if ((iNeedQueryLeft <= iRecordLeft) && (iNeedQueryRight >= iRecordRight))
      {
      return m_mData[iTreeNodeIndex];
      }
      const int iMid = (iRecordLeft + iRecordRight) / 2;
      int iRet = 0;
      if (iNeedQueryLeft <= iMid)
      {
      iRet = Query(iTreeNodeIndex * 2, iRecordLeft, iMid, iNeedQueryLeft, iNeedQueryRight);
      }
      if (iNeedQueryRight > iMid)
      {
      iRet = max(iRet, Query(iTreeNodeIndex * 2 + 1, iMid + 1, iRecordRight, iNeedQueryLeft, iNeedQueryRight));
      }
      return iRet;
      }
      void Modify(int iTreeNodeIndex, int iLeft, int iRight, int iIndex, int iValue)
      {
      if (iLeft == iRight)
      {
      m_mData[iTreeNodeIndex] = max(m_mData[iTreeNodeIndex], iValue);
      return;
      }
      const int iMid = (iLeft + iRight) / 2;
      if (iIndex <= iMid)
      {
      Modify(iTreeNodeIndex * 2, iLeft, iMid, iIndex, iValue);
      }
      else
      {
      Modify(iTreeNodeIndex * 2 + 1, iMid + 1, iRight, iIndex, iValue);
      }
      m_mData[iTreeNodeIndex] = max(m_mData[iTreeNodeIndex * 2], m_mData[iTreeNodeIndex * 2 + 1]);
      }
      const int m_iArrSize;
      std::unordered_map<int, int> m_mData;
      };

      template
      class CSumLineTree
      {
      public:
      CSumLineTree(int iEleSize) :m_iEleSize(iEleSize), m_vArr(m_iEleSize * 4), m_vChildAdd(m_iEleSize * 4)
      {

       }
       void Add(int iLeftIndex, int iRightIndex, int iValue)
       {
      	 Add(1, 1, m_iEleSize, iLeftIndex+1, iRightIndex+1, iValue);
       }
       T Query(int iLeftIndex, int iRightIndex)
       {
      	 return Query(1, 1, m_iEleSize, iLeftIndex + 1, iRightIndex + 1);
       }
      

      private:
      T Query(int iNode, int iDataLeft, int iDataRight, int iOpeLeft, int iOpeRight)
      {
      if ((iOpeLeft <= iDataLeft) && (iOpeRight >= iDataRight))
      {
      return m_vArr[iNode];
      }
      Fresh(iNode, iDataLeft, iDataRight);
      const int iMid = iDataLeft + (iDataRight - iDataLeft) / 2;
      T ret(0);
      if (iMid >= iOpeLeft)
      {
      ret += Query(iNode * 2, iDataLeft, iMid, iOpeLeft, iOpeRight);
      }
      if (iMid + 1 <= iOpeRight)
      {
      ret += Query(iNode * 2 + 1, iMid + 1, iDataRight, iOpeLeft, iOpeRight);
      }
      return ret;
      }
      /* 暴力解法
      void Add(int iNode, int iDataLeft, int iDataRight, int iOpeLeft, int iOpeRight, int iValue)
      {
      m_vArr[iNode] += T(iValue)*(min(iDataRight, iOpeRight) - max(iDataLeft, iOpeLeft)+1);
      if (iDataLeft == iDataRight)
      {
      return;
      }
      const int iMid = iDataLeft + (iDataRight - iDataLeft) / 2;
      if (iMid >= iOpeLeft)
      {
      Add(iNode * 2, iDataLeft, iMid, iOpeLeft, iOpeRight, iValue);
      }
      if (iMid + 1 <= iOpeRight)
      {
      Add(iNode * 2 + 1, iMid + 1, iDataRight, iOpeLeft, iOpeRight, iValue);
      }
      }
      /
      void Fresh(int iNode, int iDataLeft, int iDataRight)
      {
      const int iMid = iDataLeft + (iDataRight - iDataLeft) / 2;
      if (m_vChildAdd[iNode] != 0)
      {
      Add(iNode * 2, iDataLeft, iMid, iDataLeft, iMid, m_vChildAdd[iNode]);
      Add(iNode * 2 + 1, iMid + 1, iDataRight, iMid + 1, iDataRight, m_vChildAdd[iNode]);
      m_vChildAdd[iNode] = 0;
      }
      }
      //懒惰法
      void Add(int iNode, int iDataLeft, int iDataRight, int iOpeLeft, int iOpeRight, int iValue)
      {
      m_vArr[iNode] += T(iValue)
      (min(iDataRight, iOpeRight) - max(iDataLeft, iOpeLeft) + 1);
      if ((iOpeLeft <= iDataLeft) && (iOpeRight >= iDataRight))
      {
      m_vChildAdd[iNode] += T(iValue);
      return;
      }

      	 Fresh(iNode,iDataLeft,iDataRight);
      	 const int iMid = iDataLeft + (iDataRight - iDataLeft) / 2;
      	 if (iMid >= iOpeLeft)
      	 {
      		 Add(iNode * 2, iDataLeft, iMid, iOpeLeft, iOpeRight, iValue);
      	 }
      	 if (iMid + 1 <= iOpeRight)
      	 {
      		 Add(iNode * 2 + 1, iMid + 1, iDataRight, iOpeLeft, iOpeRight, iValue);
      	 }
       }
      
       const int m_iEleSize;
       vector<T> m_vArr;
       vector<int> m_vChildAdd;
      

      };

      template
      class CTreeArr
      {
      public:
      CTreeArr(int iSize) :m_vData(iSize+1)
      {

       }
       void Add(int index, T value)
       {
      	 index++;
      	 while (index < m_vData.size())
      	 {
      		 m_vData[index] += value;
      		 index += index&(-index);
      	 }
       }
       T Sum(int index)
       {
      	 index++;
      	 T ret = 0;
      	 while (index )
      	 {
      		 ret += m_vData[index];
      		 index -= index&(-index);
      	 }
      	 return ret;
       }
       T Get(int index)
       {
      	 return Sum(index) - Sum(index - 1);
       }
      

      private:
      vector m_vData;
      };

      //iCodeNum 必须大于等于可能的字符数
      template
      class CHashStr {
      public:
      CHashStr(string s, int iCodeNum, int iCodeBegin = 1, char chBegin = ‘a’) {
      m_c = s.length();
      m_vP.resize(m_c + 1);
      m_vP[0] = 1;
      m_vHash.resize(m_c + 1);
      for (int i = 0; i < m_c; i++)
      {
      const int P = iCodeBegin + iCodeNum;
      m_vHash[i + 1] = m_vHash[i] * P + s[i] - chBegin + iCodeBegin;
      m_vP[i + 1] = m_vP[i] * P;
      }
      }
      int GetHash(int left, int right)
      {
      return ( m_vHash[right + 1] - m_vHash[left] * m_vP[right - left + 1]).ToInt();
      }
      inline int GetHash(int right)
      {
      return m_vHash[right + 1].ToInt();
      }
      int m_c;
      vector<C1097Int> m_vP;
      vector<C1097Int> m_vHash;
      };

      template
      class C2HashStr
      {
      public:
      C2HashStr(string s) {
      m_pHash1 = std::make_unique<CHashStr<>>(s, 26);
      m_pHash2 = std::make_unique < CHashStr>(s, 27, 0);
      }

       long long GetHash(int left, int right)
       {
      	 return (long long)m_pHash1->GetHash(left, right)*(MOD2 + 1) + m_pHash2->GetHash(left, right);
       }
       long long GetHash( int right)
       {
      	 return (long long)m_pHash1->GetHash( right)*(MOD2 + 1) + m_pHash2->GetHash( right);
       }
      

      private:
      std::unique_ptr<CHashStr<>> m_pHash1;
      std::unique_ptr<CHashStr> m_pHash2;
      };

      template
      class CDynaHashStr {
      public:
      CDynaHashStr(int iCodeNum, int iCodeBegin = 1, char chBegin = ‘a’) :m_iUnit(iCodeNum + iCodeBegin), m_iP(1), m_iBegin(iCodeBegin - chBegin)
      {

       }
       inline void push_back(const char& ch)
       {
      	const int iNum = ch + m_iBegin;
      	m_iHash *= m_iUnit;
      	m_iHash += iNum;
      	m_iP *= m_iUnit;
       }
       inline void push_front(const char& ch)
       {
      	 const int iNum = ch + m_iBegin;
      	 m_iHash +=  m_iP*iNum;
      	 m_iP *= m_iUnit;
       }
       inline int GetHash() const
       {
      	 return m_iHash;
       }
       const int m_iUnit;
       const int m_iBegin;
       C1097Int<MOD> m_iHash;
       C1097Int<MOD> m_iP;
      

      };

      template
      class C2DynaHashStr {
      public:
      C2DynaHashStr(int iCodeNum, int iCodeBegin = 1, char chBegin = ‘a’)
      {
      m_pHash1 = new CDynaHashStr<>(iCodeNum, iCodeBegin, chBegin);
      m_pHash2 = new CDynaHashStr(iCodeNum, iCodeBegin, chBegin);
      }
      ~C2DynaHashStr()
      {
      delete m_pHash1;
      delete m_pHash2;
      }
      inline void push_back(const char& ch)
      {
      m_pHash1->push_back(ch);
      m_pHash2->push_back(ch);
      }
      inline void push_front(const char& ch)
      {
      m_pHash1->push_front(ch);
      m_pHash2->push_front(ch);
      }
      long long Hash()const
      {
      return (long long)MOD2m_pHash1->m_iHash.ToInt() + m_pHash2->m_iHash.ToInt();
      }
      bool operator==(const C2DynaHashStr& other) const
      {
      return (m_pHash1->m_iHash.ToInt() == other.m_pHash1->m_iHash.ToInt()) && (m_pHash2->m_iHash.ToInt() == other.m_pHash2->m_iHash.ToInt());
      }
      CDynaHashStr<>
      m_pHash1;
      CDynaHashStr* m_pHash2 ;
      };
      namespace NSort
      {
      template
      bool SortVecVec(const vector& v1, const vector& v2)
      {
      return v1[ArrIndex] < v2[ArrIndex];
      };
      }

      namespace NCmp
      {
      template
      bool Less(const std::pair<Class1, int>& p, Class1 iData)
      {
      return p.first < iData;
      }

       template<class Class1>
       bool  Greater(const std::pair<Class1, int>& p, Class1 iData)
       {
      	 return p.first > iData;
       }
      
      template<class _Ty1,class _Ty2>
      class CLessPair
      {
      public:
      	bool operator()(const std::pair<_Ty1, _Ty2>& p1, const std::pair<_Ty1, _Ty2>& p2)const
      	{
      		return p1.first < p2.first;
      	}
      };
      
      template<class _Ty1, class _Ty2>
      class CGreatePair
      {
      public:
      	bool operator()(const std::pair<_Ty1, _Ty2>& p1, const std::pair<_Ty1, _Ty2>& p2)const
      	{
      		return p1.first > p2.first;
      	}
      };
      

      }

      class CIndexVector
      {
      public:
      template
      CIndexVector(vector& data)
      {
      for (int i = 0; i < data.size(); i++)
      {
      m_indexs.emplace_back(i);
      }
      std::sort(m_indexs.begin(), m_indexs.end(), [data](const int& i1, const int& i2)
      {
      return data[i1] < data[i2];
      });
      }
      int GetIndex(int index)
      {
      return m_indexs[index];
      }
      private:
      vector m_indexs;
      };

      class CMedian
      {
      public:
      void AddNum(int iNum)
      {
      m_queTopMin.emplace(iNum);
      MakeNumValid();
      MakeSmallBig();
      }
      void Remove(int iNum)
      {
      if (m_queTopMax.size() && (iNum <= m_()))
      {
      m_setTopMaxDel.insert(iNum);
      }
      else
      {
      m_setTopMinDel.insert(iNum);
      }

      	PopIsTopIsDel(m_queTopMin, m_setTopMinDel);
      	PopIsTopIsDel(m_queTopMax, m_setTopMaxDel);
      	MakeNumValid();
      	MakeSmallBig();
      }
      double Median()
      {
      	const int iMaxNum = m_queTopMin.size() - m_setTopMinDel.size();
      	const int iMinNum = m_queTopMax.size() - m_setTopMaxDel.size();
      	if (iMaxNum > iMinNum)
      	{
      		return m_();
      	}
      	return ((double)m_() + m_())/2.0;
      }
      template<class T>
      void PopIsTopIsDel(T& que, std::unordered_multiset<int>& setTopMaxDel)
      {
      	while (que.size() && (setTopMaxDel.count(())))
      	{
      		setTopMaxDel.erase(setTopMaxDel.find(()));
      		que.pop();
      	}
      }
      void MakeNumValid()
      {
      	const int iMaxNum = m_queTopMin.size() - m_setTopMinDel.size();
      	const int iMinNum = m_queTopMax.size() - m_setTopMaxDel.size();
      	//确保两个队的数量
      	if (iMaxNum > iMinNum + 1)
      	{
      		int tmp = m_();
      		m_queTopMin.pop();
      		m_queTopMax.emplace(tmp);
      		PopIsTopIsDel(m_queTopMin, m_setTopMinDel);
      	}
      	if (iMinNum > iMaxNum)
      	{
      		int tmp = m_();
      		m_queTopMax.pop();
      		m_queTopMin.push(tmp);
      		PopIsTopIsDel(m_queTopMax, m_setTopMaxDel);
      	}
      }
      void MakeSmallBig()
      {
      	if (m_queTopMin.empty() || m_queTopMax.empty())
      	{
      		return;
      	}
      	while (m_() < m_())
      	{
      		const int iOldTopMin = m_();
      		const int iOldTopMax = m_();
      		m_queTopMin.pop();
      		m_queTopMax.pop();
      		m_queTopMin.emplace(iOldTopMax);
      		m_queTopMax.emplace(iOldTopMin);
      		PopIsTopIsDel(m_queTopMin, m_setTopMinDel);
      		PopIsTopIsDel(m_queTopMax, m_setTopMaxDel);
      	}
      }
      std::priority_queue<int> m_queTopMax;
      std::priority_queue<int, vector<int>, greater<int>> m_queTopMin;
      std::unordered_multiset<int> m_setTopMaxDel, m_setTopMinDel;
      

      };

      template
      class CDistanceGrid
      {
      public:
      CDistanceGrid(const vector<vector>& grid) :m_grid(grid), m_r(grid.size()), m_c(grid[0].size())
      {

      }
      //单源路径 D 算法 ,时间复杂度:r*c*log(r*c)
      inline int Dis(int r1, int c1, int r2, int c2)
      {	
      	vector<vector<int>> vDis(iMaxRow, vector<int>(iMaxCol, INT_MAX));
      
      	auto Add = [&vDis, this](std::priority_queue<pair<int, int>, vector<std::pair<int, int>>, greater<pair<int, int>>>& queCur, int iDis, int r, int c)
      	{
      		const int iRowColMask = iMaxCol * r + c;
      		if (iDis >= vDis[r][c])
      		{
      			return;
      		}
      		queCur.emplace(iDis,iRowColMask);
      		vDis[r][c] = iDis;
      	};
      	auto Move = [&](std::priority_queue<pair<int, int>, vector<std::pair<int, int>>, greater<pair<int, int>>>& queCur, int iDis, int r, int c)
      	{
      		if ((r < 0) || (r >= m_r))
      		{
      			return;
      		}
      		if ((c < 0) || (c >= m_c))
      		{
      			return;
      		}
      		if (m_grid[r][c] < 1)
      		{
      			return;
      		}
      		Add(queCur,iDis, r, c);
      	};
      
      	std::priority_queue<pair<int, int>, vector<std::pair<int, int>>, greater<pair<int, int>>> que;		
      	Add(que,0,r1, c1);
      	while (que.size())
      	{
      		const int iDis = ().first;
      		const int iStart = ().second;
      		que.pop();
      		const int r = iStart / iMaxCol;
      		const int c = iStart % iMaxCol;
      		if ((r == r2) && (c == c2))
      		{
      			return iDis;
      		}
      		if (iDis > vDis[r][c])
      		{
      			continue;
      		}
      		
      		Move(que, iDis + 1, r + 1, c);
      		Move(que, iDis + 1, r - 1, c);
      		Move(que, iDis + 1, r, c + 1);
      		Move(que, iDis + 1, r, c - 1);
      	}
      
      	return -1;
      }
      

      private:
      virtual bool IsCanMoveStatue(int r, int c)
      {
      return m_grid[r][c] >= 1;
      }
      const int m_r;
      const int m_c;
      const vector<vector>& m_grid;

      };

      class CBFSGridDist
      {
      public:
      CBFSGridDist(const vector<vector>& bCanVisit, int r, int c) :m_bCanVisit(bCanVisit), m_r(m_bCanVisit.size()), m_c(m_bCanVisit[0].size())
      {
      m_vDis.assign(m_r, vector(m_c,INT_MAX/2));
      Dist(r, c);
      }
      bool Vilid(const int r,const int c )
      {
      if ((r < 0) || (r >= m_r))
      {
      return false;
      }
      if ((c < 0) || (c >= m_c))
      {
      return false;
      }
      return true;
      }
      const vector<vector>& Dis()const
      {
      return m_vDis;
      }
      const vector<vector>& m_bCanVisit;
      private:
      //INT_MAX/2 表示无法到达
      void Dist(int r, int c)
      {
      m_vDis.assign(m_r, vector(m_c, INT_MAX / 2));
      vector<vector> vHasDo(m_r, vector(m_c));
      std::queue<std::pair<int, int>> que;
      auto Add = [&](const int& r, const int& c, const int& iDis)
      {
      if (!Vilid(r, c))
      {
      return;
      }
      if (vHasDo[r][c])
      {
      return;
      }
      if (!m_bCanVisit[r][c])
      {
      vHasDo[r][c] = true;
      return;
      }
      if (iDis >= m_vDis[r][c])
      {
      return;
      }

      		que.emplace(r, c);
      		m_vDis[r][c] = iDis;
      		vHasDo[r][c] = true;
      	};
      	Add(r, c, 0);
      	while (que.size())
      	{
      		const int r = que.front().first;
      		const int c = que.front().second;
      		que.pop();
      		const int iDis = m_vDis[r][c];
      		Add(r + 1, c, iDis + 1);
      		Add(r - 1, c, iDis + 1);
      		Add(r, c + 1, iDis + 1);
      		Add(r, c - 1, iDis + 1);
      	}
      
      }
      vector<vector<int>> m_vDis;
      const int m_r;
      const int m_c;
      

      };

      class C2BNumTrieNode
      {
      public:
      C2BNumTrieNode()
      {
      m_childs[0] = m_childs[1] = nullptr;
      }
      bool GetNot0Child(bool bFirstRight)
      {
      auto ptr = m_childs[bFirstRight];
      if (ptr && (ptr->m_iNum >0))
      {
      return bFirstRight;
      }
      return !bFirstRight;
      }
      int m_iNum = 0;
      C2BNumTrieNode* m_childs[2];
      };

      template
      class C2BNumTrie
      {
      public:
      C2BNumTrie()
      {
      m_pRoot = new C2BNumTrieNode();
      }
      void Add(int iNum)
      {
      m_setHas.emplace(iNum);
      C2BNumTrieNode* p = m_pRoot;
      for (int i = iLeveNum - 1; i >= 0; i–)
      {
      p->m_iNum++;
      bool bRight = iNum & (1 << i);
      if (nullptr == p->m_childs[bRight])
      {
      p->m_childs[bRight] = new C2BNumTrieNode();
      }
      p = p->m_childs[bRight];
      }
      p->m_iNum++;
      }
      void Del(int iNum)
      {
      auto it = m_setHas.find(iNum);
      if (m_setHas.end() == it)
      {
      return;
      }
      m_setHas.erase(it);
      C2BNumTrieNode* p = m_pRoot;
      for (int i = iLeveNum - 1; i >= 0; i–)
      {
      p->m_iNum–;
      bool bRight = iNum & (1 << i);
      p = p->m_childs[bRight];
      }
      p->m_iNum–;
      }
      int MaxXor(int iNum)
      {
      C2BNumTrieNode* p = m_pRoot;
      int iRet = 0;
      for (int i = iLeveNum - 1; i >= 0; i–)
      {
      bool bRight = !(iNum & (1 << i));
      bool bSel = p->GetNot0Child(bRight);
      p = p->m_childs[bSel];
      if (bSel == bRight)
      {
      iRet |= (1 << i);
      }
      }
      return iRet;
      }
      C2BNumTrieNode* m_pRoot;
      std::unordered_multiset m_setHas;
      };

      struct SValueItem
      {
      SValueItem()
      {

      }
      SValueItem(int iValue)
      {
      	m_iCoefficient = iValue;
      }
      SValueItem operator*(const SValueItem& o)const
      {
      	SValueItem ret(m_iCoefficient*o.m_iCoefficient);
      	int i = 0, j = 0;
      	while ((i < m_vVars.size()) && (j < o.m_vVars.size()))
      	{
      		if (m_vVars[i] < o.m_vVars[j])
      		{
      			ret.m_vVars.emplace_back(m_vVars[i]);
      			i++;
      		}
      		else
      		{
      			ret.m_vVars.emplace_back(o.m_vVars[j]);
      			j++;
      		}
      	}
      	ret.m_vVars.insert(ret.m_vVars.end(), m_vVars.begin()+i, m_vVars.end());
      	ret.m_vVars.insert(ret.m_vVars.end(), o.m_vVars.begin()+j, o.m_vVars.end());
      	return ret;
      }
      bool operator<(const SValueItem& o)const
      {
      	if (m_vVars.size() == o.m_vVars.size())
      	{
      		return m_vVars < o.m_vVars;
      	}
      	return m_vVars.size() > o.m_vVars.size();
      }
      vector<std::string> m_vVars;
      int m_iCoefficient=1;//系数、倍率
      std::string ToString()const
      {
      	std::ostringstream os;
      	os << m_iCoefficient ;
      	for (const auto&s : m_vVars)
      	{
      		os << "*" << s;
      	}
      	return os.str();
      }
      

      };

      struct SValue
      {
      SValue()
      {

      }
      SValue(int iValue)
      {
      	SValueItem item;
      	item.m_iCoefficient = iValue;
      	m_items.emplace(item);
      }
      SValue(std::string strName)
      {
      	SValueItem item;
      	item.m_vVars.emplace_back(strName);
      	m_items.emplace(item);
      }
      SValue operator-(const SValue& o)const
      {
      	SValue ret;
      	ret.m_items = m_items;
      	for (auto it : o.m_items)
      	{
      		ret -= it;
      	}
      	return ret;
      }
      SValue operator+(const SValue& o)const
      {
      	SValue ret;
      	ret.m_items = m_items;
      	for (auto it : o.m_items)
      	{
      		ret += it;
      	}			
      	return ret;
      }
      SValue operator*(const SValue& o)const
      {
      	SValue ret;
      	for (const auto it : m_items)
      	{
      		for (const auto ij : o.m_items)
      		{
      			ret += it*ij;
      		}
      	}
      	return ret;
      }
      SValue& operator+=(const SValueItem& item)
      {
      	auto it = m_items.find(item);
      	if (m_items.end() == it)
      	{
      		m_items.emplace(item);
      	}
      	else
      	{
      		auto tmp = *it;
      		tmp.m_iCoefficient += item.m_iCoefficient;
      		m_items.erase(it);
      		m_items.emplace(tmp);
      	}
      	return *this;
      }
      SValue& operator-=(const SValueItem& item)
      {
      	auto it = m_items.find(item);
      	if (m_items.end() == it)
      	{
      		auto tmp = item;
      		tmp.m_iCoefficient *= -1;
      		m_items.emplace(tmp);
      	}
      	else
      	{
      		auto tmp = *it;
      		tmp.m_iCoefficient -= item.m_iCoefficient;
      		m_items.erase(it);
      		m_items.emplace(tmp);
      	}
      	return *this;
      }
      vector<std::string> ToStrings()const
      {
      	vector<std::string> vRet;
      	for (const auto& item : m_items)
      	{
      		if (0 == item.m_iCoefficient)
      		{
      			continue;
      		}
      		vRet.emplace_back(item.ToString());
      	}
      	return vRet;
      }
      std::set<SValueItem> m_items;
      

      };

      class CDelIndexs
      {
      public:
      CDelIndexs()
      {

      }
      CDelIndexs(int iSize)
      {
      	Init(iSize);
      }
      void Init(int iSize)
      {
      	m_bDels.assign(iSize, false);
      	m_vNext.resize(iSize);
      	for (int i = 0; i < iSize; i++)
      	{
      		m_vNext[i] = i + 1;
      	}
      }
      void Del(int index)
      {
      	if ((index < 0) || (index >= m_vNext.size()))
      	{
      		return;
      	}
      	if (m_bDels[index])
      	{
      		return;
      	}
      	m_bDels[index] = true;
      
      }
      void SetCur(int index)
      {
      	if (index < 0)
      	{
      		m_iCur = m_vNext.size();
      	}
      	else
      	{
      		m_iCur = FreshCur(index);
      	}
      }
      int NextIndex()
      {
      	if (m_iCur >= m_vNext.size())
      	{
      		return -1;
      	}
      	auto ret = m_iCur;
      	SetCur(m_vNext[m_iCur]);
      	return ret;
      }
      

      private:
      int FreshCur(int index)
      {
      if (index >= m_vNext.size())
      {
      return m_vNext.size();
      }
      if (!m_bDels[index])
      {
      return index;
      }

      	return m_vNext[index] = FreshCur(m_vNext[index]);
      }
      int m_iCur = 0;
      vector<bool> m_bDels;
      vector<int> m_vNext;
      

      };

      class CUnionFind
      {
      public:
      CUnionFind(int iSize) :m_vConnetNO(iSize), m_vConnectSize(iSize, 1)
      {
      for (int i = 0; i < iSize; i++)
      {
      m_vConnetNO[i] = i;
      }
      m_iConnetSize = iSize;
      }
      int GetConnectNO(int iNode)
      {
      int& iConnectNO = m_vConnetNO[iNode];
      if (iNode == iConnectNO)
      {
      return iNode;
      }
      return iConnectNO = GetConnectNO(iConnectNO);
      }
      void Union(int iNode1, int iNode2)
      {
      const int iConnectNO1 = GetConnectNO(iNode1);
      const int iConnectNO2 = GetConnectNO(iNode2);
      if (iConnectNO1 == iConnectNO2)
      {
      return ;
      }
      m_iConnetSize–;
      if (iConnectNO1 > iConnectNO2)
      {
      UnionConnect(iConnectNO1, iConnectNO2);
      }
      else
      {
      UnionConnect(iConnectNO2, iConnectNO1);
      }
      }
      int GetAConnectSizeByNode(int iNode)
      {
      return m_vConnectSize[GetConnectNO(iNode)];
      }
      bool IsConnect(int iNode1, int iNode2)
      {
      return GetConnectNO(iNode1) == GetConnectNO(iNode2);
      }
      int ConnetSize()const
      {
      return m_iConnetSize;
      }
      private:
      void UnionConnect(int iFrom, int iTo)
      {
      m_vConnectSize[iTo] += m_vConnectSize[iFrom];
      m_vConnetNO[iFrom] = iTo;
      }
      vector m_vConnetNO;//各点所在联通区域的编号,本联通区域任意一点的索引,为了增加可理解性,用最小索引
      vector m_vConnectSize;//各联通区域点数量
      int m_iConnetSize;
      };

      class CUnionFindMST
      {
      public:
      CUnionFindMST(const int iNodeSize) :m_uf(iNodeSize)
      {

      }
      void AddEdge(const int iNode1, const int iNode2, int iWeight)
      {
      	if (m_uf.IsConnect(iNode1, iNode2))
      	{
      		return;
      	}
      	m_iMST += iWeight;
      	m_uf.Union(iNode1, iNode2);
      }
      void AddEdge(const vector<int>& v )
      {
      	AddEdge(v[0], v[1], v[2]);
      }
      int MST()
      {
      	if (m_uf.ConnetSize() > 1)
      	{
      		return -1;
      	}
      	return m_iMST;
      }
      

      private:
      int m_iMST = 0;
      CUnionFind m_uf;
      };

      class CNearestMST
      {
      public:
      CNearestMST(const int iNodeSize) :m_bDo(iNodeSize), m_vDis(iNodeSize, INT_MAX), m_vNeiTable(iNodeSize)
      {

      }
      void Init(const vector<vector<int>>& edges)
      {
      	for (const auto& v : edges)
      	{
      		Add(v);
      	}
      }
      void Add(const vector<int>& v )
      {
      	m_vNeiTable[v[0]].emplace_back(v[1], v[2]);
      	m_vNeiTable[v[1]].emplace_back(v[0], v[2]);
      }
      int MST(int start)
      {
      	int next = start;
      	while ((next = AddNode(next)) >= 0);
      	return m_iMST;
      }
      int MST(int iNode1, int iNode2,int iWeight)
      {
      	m_bDo[iNode1] = true;
      	for (const auto& it : m_vNeiTable[iNode1])
      	{
      		if (m_bDo[it.first])
      		{
      			continue;
      		}
      		m_vDis[it.first] = min(m_vDis[it.first],(long long) it.second);
      	}
      	m_iMST = iWeight;
      
      	int next = iNode2;
      	while ((next = AddNode(next)) >= 0);
      	return m_iMST;
      }
      

      private:
      int AddNode(int iCur)
      {
      m_bDo[iCur] = true;
      for (const auto& it : m_vNeiTable[iCur])
      {
      if (m_bDo[it.first])
      {
      continue;
      }
      m_vDis[it.first] = min(m_vDis[it.first], (long long)it.second);
      }

      	int iMinIndex = -1;
      	for (int i = 0; i < m_vDis.size(); i++)
      	{
      		if (m_bDo[i])
      		{
      			continue;
      		}
      		if ((-1 == iMinIndex) || (m_vDis[i] < m_vDis[iMinIndex]))
      		{
      			iMinIndex =i;		
      		}
      	}
      	if ( -1 != iMinIndex)
      	{
      		if (INT_MAX == m_vDis[iMinIndex])
      		{
      			m_iMST = -1;
      			return -1;
      		}
      		m_iMST += m_vDis[iMinIndex];
      	}
      	
      	return iMinIndex;
      }
      vector<bool> m_bDo;
      vector<long long> m_vDis;
      vector < vector<std::pair<int, int>>> m_vNeiTable;
      long long m_iMST = 0;
      

      };

      typedef pair<long long,int> PAIRLLI;
      class CDis
      {
      public:
      static void Dis(vector& vDis, int start, const vector<vector<pair<int, int>>>& vNeiB)
      {
      std::priority_queue<PAIRLLI, vector, greater> minHeap;
      minHeap.emplace(0, start);
      while (minHeap.size())
      {
      const long long llDist = ().first;
      const int iCur = ().second;
      minHeap.pop();
      if (-1 != vDis[iCur])
      {
      continue;
      }
      vDis[iCur] = llDist;
      for (const auto& it : vNeiB[iCur])
      {
      minHeap.emplace(llDist + it.second, it.first);
      }
      }

      }
      

      };

      class CNearestDis
      {
      public:
      CNearestDis(int iSize) :m_iSize(iSize), DIS(m_vDis), PRE(m_vPre)
      {

      }
      void Cal(int start, const vector<vector<pair<int, int>>>& vNeiB)
      {
      	m_vDis.assign(m_iSize, -1);
      	m_vPre.assign(m_iSize, -1);
      	vector<bool> vDo(m_iSize);//点是否已处理
      	auto AddNode = [&](int iNode)
      	{
      		//const int iPreNode = m_vPre[iNode];
      		long long llPreDis = m_vDis[iNode];
      
      		vDo[iNode] = true;
      		for (const auto& it : vNeiB[iNode])
      		{
      			if (vDo[it.first])
      			{
      				continue;
      			}
      
      			if ((-1 == m_vDis[it.first]) || (it.second + llPreDis < m_vDis[it.first]))
      			{
      				m_vDis[it.first] = it.second + llPreDis;
      				m_vPre[it.first] = iNode;
      			}				
      		}
      
      		long long llMinDis = LLONG_MAX;
      		int iMinIndex = -1;
      		for (int i = 0; i < m_vDis.size(); i++)
      		{
      			if (vDo[i])
      			{
      				continue;
      			}
      			if (-1 == m_vDis[i])
      			{
      				continue;
      			}
      			if (m_vDis[i] < llMinDis)
      			{
      				iMinIndex = i;
      				llMinDis = m_vDis[i];
      			}
      		}
      		return (LLONG_MAX == llMinDis) ? -1 : iMinIndex;
      	};
      
      	int next = start;
      	m_vDis[start] = 0;
      	while (-1 != (next= AddNode(next)));
      }
      void Cal(const int start, vector<vector<int>>& edges)
      {
      	vector<vector<pair<int, int>>> vNeiB(m_iSize);
      	for (int i = 0; i < edges.size(); i++)
      	{
      		const auto& v = edges[i];
      		vNeiB[v[0]].emplace_back(v[1], v[2]);
      		vNeiB[v[1]].emplace_back(v[0], v[2]);
      	}
      	Cal(start, vNeiB);
      }
      const vector<long long>& DIS;
      const vector<int>& PRE;
      

      private:
      const int m_iSize;
      vector m_vDis;//各点到起点的最短距离
      vector m_vPre;//最短路径的前一点
      };

      class CNeiBo2
      {
      public:
      CNeiBo2(int n, vector<vector>& edges, bool bDirect)
      {
      m_vNeiB.resize(n);
      for (const auto& v : edges)
      {
      m_vNeiB[v[0]].emplace_back(v[1]);
      if (!bDirect)
      {
      m_vNeiB[v[1]].emplace_back(v[0]);
      }
      }
      }
      vector<vector> m_vNeiB;
      };

      struct SDecimal
      {
      SDecimal(int iNum=0, int iDeno = 1)
      {
      m_iNum = iNum;
      m_iDeno = iDeno;
      int iGCD = GCD(abs(m_iNum), abs(m_iDeno));
      m_iNum /= iGCD;
      m_iDeno /= iGCD;
      if (m_iDeno < 0)
      {
      m_iDeno = -m_iDeno;
      m_iNum = -m_iNum;
      }
      }
      SDecimal operator*(const SDecimal& o)const
      {
      return SDecimal(m_iNumo.m_iNum, m_iDenoo.m_iDeno);
      }
      SDecimal operator/(const SDecimal& o)const
      {
      return SDecimal(m_iNumo.m_iDeno, m_iDenoo.m_iNum);
      }
      SDecimal operator+(const SDecimal& o)const
      {
      const int iGCD = GCD(m_iDeno, o.m_iDeno);
      const int iDeno = m_iDenoo.m_iDeno / iGCD;
      return SDecimal(m_iNum
      (iDeno / m_iDeno) + o.m_iNum*(iDeno / o.m_iDeno), iDeno);
      }
      SDecimal operator-(const SDecimal& o)const
      {
      const int iGCD = GCD(m_iDeno, o.m_iDeno);
      const int iDeno = m_iDenoo.m_iDeno / iGCD;
      return SDecimal(m_iNum
      (iDeno / m_iDeno) - o.m_iNum*(iDeno / o.m_iDeno), iDeno);
      }
      bool operator==(const SDecimal& o)const
      {
      return (m_iNum == o.m_iNum) && (m_iDeno == o.m_iDeno);
      }
      bool operator<(const SDecimal& o)const
      {
      auto tmp = *this - o;
      return tmp.m_iNum < 0;
      }
      int m_iNum=0;//分子
      int m_iDeno=1;//分母
      };

      struct point{
      double x, y;
      point(double i, double j) :x(i), y(j){}
      };

      //算两点距离
      double dist(double x1, double y1, double x2, double y2){
      return sqrt((x1 - x2)(x1 - x2) + (y1 - y2)(y1 - y2));
      }

      //计算圆心
      point CircleCenter(point& a, point& b, int r){
      //算中点
      point mid((a.x + b.x) / 2.0, (a.y + b.y) / 2.0);
      //AB距离的一半
      double d = dist(a.x, a.y, mid.x, mid.y);
      //计算h
      double h = sqrt(rr - dd);
      //计算垂线
      point ba(b.x - a.x, b.y - a.y);
      point hd(-ba.y, ba.x);
      double len = sqrt(hd.xhd.x + hd.yhd.y);
      hd.x /= len, hd.y /= len;
      hd.x *= h, hd.y *= h;
      return point(hd.x + mid.x, hd.y + mid.y);
      }

      class C01LineTree
      {
      public:
      C01LineTree(const vector& nums) :m_iEleSize(nums.size())
      {
      m_arr.resize(m_iEleSize * 4);
      Init(nums,1, 1, m_iEleSize);
      m_vNeedFreshChilds.assign(m_iEleSize * 4, false);
      }
      void Rotato(int iLeftZeroIndex,int iRightZeroIndex )
      {
      int iRotatoLeft = iLeftZeroIndex + 1;
      int iRotatoRight = iRightZeroIndex + 1;
      Rotato(1, 1, m_iEleSize, iRotatoLeft, iRotatoRight);
      }
      int Query()
      {
      return m_arr[1];
      }
      private:
      void Rotato(int iSaveIndex, int iDataBegin, int iDataEnd, int iRotatoLeft, int iRotatoRight)
      {
      if ((iRotatoLeft <= iDataBegin) && (iRotatoRight >= iDataEnd))
      {//整个范围需要更新
      RotatoSelf(iSaveIndex, iDataBegin, iDataEnd);
      return;
      }

      	int iMid = iDataBegin + (iDataEnd - iDataBegin) / 2;
      	if (m_vNeedFreshChilds[iSaveIndex])
      	{
      		RotatoSelf(iSaveIndex * 2, iDataBegin, iMid);
      		RotatoSelf(iSaveIndex * 2 + 1, iMid + 1, iDataEnd);
      		m_vNeedFreshChilds[iSaveIndex] = false;
      	}	
      	if (iMid >= iRotatoLeft)
      	{
      		Rotato(iSaveIndex * 2, iDataBegin, iMid, iRotatoLeft, iRotatoRight);
      	}
      	if (iMid + 1 <= iRotatoRight)
      	{
      		Rotato(iSaveIndex * 2 + 1, iMid + 1, iDataEnd, iRotatoLeft, iRotatoRight);
      	}
      	m_arr[iSaveIndex] = m_arr[iSaveIndex * 2] + m_arr[iSaveIndex * 2 + 1];
      }
      void RotatoSelf(int iSaveIndex, int iDataBegin, int iDataEnd)
      {
      	//总数量 - 翻转后0(翻转前1)的数量
      	m_arr[iSaveIndex] = (iDataEnd - iDataBegin + 1) - m_arr[iSaveIndex];
      	//懒惰法,标记本节点的子孙节点没更新
      	m_vNeedFreshChilds[iSaveIndex] = !m_vNeedFreshChilds[iSaveIndex];
      }
      void Init(const vector<int>& nums, int iSaveIndex,int iDataBegin, int iDataEnd)
      {
      	if (iDataBegin == iDataEnd)
      	{
      		m_arr[iSaveIndex] = nums[iDataBegin - 1];
      		return;
      	}
      	int iMid = iDataBegin + (iDataEnd - iDataBegin) / 2;
      	Init(nums, iSaveIndex * 2  , iDataBegin, iMid);
      	Init(nums, iSaveIndex * 2 + 1, iMid + 1, iDataEnd);
      	m_arr[iSaveIndex] = m_arr[iSaveIndex * 2] + m_arr[iSaveIndex * 2 + 1];
      }
      const int m_iEleSize;
      vector<int> m_arr;
      vector<bool> m_vNeedFreshChilds;
      

      };

      /*
      struct TreeNode {
      int val;
      TreeNode *left;
      TreeNode *right;
      TreeNode(int x) : val(x), left(NULL), right(NULL) {}
      TreeNode(int x, int iLeft) : val(x), left(new TreeNode(iLeft)), right(nullptr) {}
      TreeNode(int x, int iLeft, int iRghit) : val(x), left(new TreeNode(iLeft)), right(new TreeNode(iRghit)) {}
      };

      namespace NTree
      {
      TreeNode* Init(const vector& nums, int iNull = 10000)
      {
      if (0 == nums.size())
      {
      return nullptr;
      }
      vector<TreeNode*> ptrs(nums.size() + 1), ptrParent(1);
      for (int i = 0; i < nums.size(); i++)
      {
      if (iNull == nums[i])
      {
      continue;
      }
      const int iNO = i + 1;
      ptrs[iNO] = new TreeNode(nums[i]);
      ptrParent.emplace_back(ptrs[iNO]);
      if (1 == iNO)
      {
      continue;
      }
      if (iNO & 1)
      {//奇数是右支
      ptrParent[iNO / 2]->right = ptrs[iNO];
      }
      else
      {
      ptrParent[iNO / 2]->left = ptrs[iNO];
      }
      }
      return ptrs[1];
      }
      }
      */

      class Solution {
      public:
      int kInversePairs(int n, int k) {
      //n为1时,只有一种情况:逆序0
      vector<C1097Int<>> pre = { C1097Int<>(1) };
      for (int i = 2; i <= n; i++)
      {
      const int iNewLen = min(k + 1, (int)pre.size() + i);
      vector<C1097Int<>> dp(iNewLen);
      C1097Int<> iSum = 0;
      for (int j = 0; j < iNewLen; j++)
      {
      if (j < pre.size())
      {
      iSum += pre[j];
      }
      const int iDelIndex = j - i;
      if (iDelIndex >= 0)
      {
      iSum -= pre[iDelIndex];
      }
      dp[j] = iSum;
      }
      pre.swap(dp);
      }
      return (k < pre.size()) ? pre[k].ToInt() : 0;
      }
      };

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.csdn.net/he_zhidan/article/details/135560044,作者:闻缺陷则喜何志丹,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:【密码学】Miller-Rabin素性检测(C++代码实现)

      下一篇:【递归】C++算法:124 二叉树中的最大路径和

      相关文章

      2025-05-19 09:04:44

      使用DoubleLinkedList扩展类,允许Add,Remove,Contains

      使用DoubleLinkedList扩展类,允许Add,Remove,Contains

      2025-05-19 09:04:44
      class , list , null , 扩展
      2025-05-19 09:04:22

      C# byte[] 如何转换成byte*

      C# byte[] 如何转换成byte*

      2025-05-19 09:04:22
      byte , int
      2025-05-16 09:15:10

      C语言练习之猜名次-----A选手说:B第二,我第三;B选手说:我第二,E第四;C选手说:我第一,D第二;D选手说:C最后,我第三;E选手说:我第四,A第一;

      C语言练习之猜名次-----A选手说:B第二,我第三;B选手说:我第二,E第四;C选手说:我第一,D第二;D选手说:C最后,我第三;E选手说:我第四,A第一;

      2025-05-16 09:15:10
      amp , lt , 排名
      2025-05-14 10:33:16

      30天拿下Rust之字符串

      在Rust中,字符串是一种非常重要的数据类型,用于处理文本数据。Rust的字符串是以UTF-8编码的字节序列,主要有两种类型:&str和String。其中,&str是一个对字符数据的不可变引用,更像是对现有字符串数据的“视图”,而String则是一个独立、可变更的字符串实体。

      2025-05-14 10:33:16
      amp , Rust , str , String , 使用 , 字符串 , 方法
      2025-05-14 10:33:16

      30天拿下Rust之切片

      在Rust中,切片是一种非常重要的引用类型。它允许你安全地引用一段连续内存中的数据,而不需要拥有这些数据的所有权。切片不包含分配的内存空间,它仅仅是一个指向数据开始位置和长度的数据结构。

      2025-05-14 10:33:16
      amp , end , 切片 , 字符串 , 引用 , 索引 , 迭代
      2025-05-14 10:03:05

      C++ 11新特性之完美转发

      在C++编程语言的演进过程中,C++ 11标准引入了一系列重大革新,其中之一便是“完美转发”机制。这一特性使得模板函数能够无损地传递任意类型的实参给其他函数或构造函数,从而极大地增强了C++在泛型编程和资源管理方面的灵活性与效率。

      2025-05-14 10:03:05
      amp , 函数 , 右值 , 引用 , 模板 , 类型
      2025-05-13 09:50:28

      分隔链表-146. LRU 缓存

      给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

      2025-05-13 09:50:28
      int , key , LinkedHashMap , 缓存 , 节点 , 链表
      2025-05-12 08:58:16

      O(1) 时间插入、删除和获取随机元素

      O(1) 时间插入、删除和获取随机元素

      2025-05-12 08:58:16
      int , val , 元素 , 返回
      2025-05-12 08:43:47

      LRU 缓存

      请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。

      2025-05-12 08:43:47
      int , key , lt , 关键字 , 缓存
      2025-05-09 08:51:21

      php array_walk break跳出循环的方法

      php array_walk break跳出循环的方法

      2025-05-09 08:51:21
      array , break , return , 场景 , 循环 , 抛出
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5255064

      查看更多

      最新文章

      C# byte[] 如何转换成byte*

      2025-05-19 09:04:22

      C语言练习之猜名次-----A选手说:B第二,我第三;B选手说:我第二,E第四;C选手说:我第一,D第二;D选手说:C最后,我第三;E选手说:我第四,A第一;

      2025-05-16 09:15:10

      C++ 11新特性之完美转发

      2025-05-14 10:03:05

      O(1) 时间插入、删除和获取随机元素

      2025-05-12 08:58:16

      Java基础(Arrays工具类)(asList()方法)(详细)

      2025-05-09 08:50:35

      C语言:深入理解指针(2)

      2025-05-07 09:09:52

      查看更多

      热门文章

      Java中创建对象的方式

      2023-02-13 09:25:28

      java之十一 Java GUI

      2024-09-25 10:13:34

      Java高级之类.class和类实例.getClass()

      2023-06-20 09:12:44

      Java学习基本类型包装类--Integer

      2023-08-09 06:41:04

      实用抽象类和接口的区别

      2023-06-28 09:11:48

      Spring Cloud Alibaba入门五:openFeign实现REST调用-构造多参数请求

      2024-09-25 10:14:48

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      C语言数据类型和变量(上)

      【动态规划】【二分查找】C++算法 466 统计重复个数

      【动态规划】【 数学】C++算法:514自由之路

      【数位dp】【动态规划】C++算法:233.数字 1 的个数

      【动态规划】【C++算法】801. 使序列递增的最小交换次数

      简单的工作者线程封装

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号