自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

chr1stopher

Dancer on the keyboard

  • 博客(181)
  • 收藏
  • 关注

原创 求乘法逆元方法总结

目录简介扩展欧几里得法IdeaCode快速幂法IdeaCode线性求[1,n]逆元IdeaCode线性求任意n个数的逆元IdeaCode简介若有线性同余方程 ax≡1(mod p)ax\equiv 1\left( mod~p\right)ax≡1(mod p),则称 xxx 为 aaa 在模 ppp 意义下的逆元,记作 a−1a^{-1}a−1扩展欧几里得法Idea原方程 ax≡1(mod p)ax\equiv 1\left( mod~p\right)ax≡1(mod

2020-08-04 21:40:21 231 1

原创 一种卡掉SPFA的简单方法

该方法同时适用于有向图和无向图① 生成一颗以起点为根的树,树高尽量高 ( 如:起点为1的树,每个点 i 的父亲可以在 max(i-5,1) 到 i-1 随机),边权随机,同时还需计算出每个点的深度d[i]。② 对于剩下的边,两端点随机,边权在 |d[b]-d[a]| 到 |d[b]-d[a]|+...

2020-05-05 22:50:08 1983 1

原创 Leetcode 46. 全排列

Description求给定排列的全排列Codeclass Solution {public: vector<vector<int>> permute(vector<int>& nums) { vector<vector<int>>res; sort(nums.begin(), nums.end()); do{ res.push_back(nums);

2021-03-04 20:42:52 148 1

原创 Leetcode 1438. 绝对差不超过限制的最长连续子数组(双指针+单调队列)

Description给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。如果不存在满足条件的子数组,则返回 0 。Solution首先发现显然可以用双指针来计算答案,重点在于如何维护当前段内的最大最小值动态维护当前窗口内的最大值和最小值,可以采用单调队列时间复杂度O(N)O(N)O(N)空间复杂度O(N)O(N)O(N)Codeclass Solution {public:

2021-03-04 15:20:56 194 1

原创 Codeforces 621C. Wet Shark and Flower(数学 + 期望)

Source:http://codeforces.com/problemset/problem/621/CDescriptionThere are n sharks who grow flowers for Wet Shark. They are all sitting around the table, such that sharks i and i + 1 are neighbours ...

2021-03-02 15:48:36 401

原创 剑指 Offer 59 - II. 队列的最大值(单调队列)

Description请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。若队列为空,pop_front 和 max_value 需要返回 -1Solution思路与剑指 Offer 30. 包含min函数的栈 类似,本质上也是相似的空间换时间的套路。维护两个队列,一个是正常队列,一个是非降的单调(双向)队列,若当前要压入队列的元素x比单调队列尾的元素y 大,则弹出队尾元素,并继续判

2021-03-01 23:53:46 80

原创 剑指 Offer 51. 数组中的逆序对(BIT + 离散化)

Description在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。Solution比较裸的求逆序对,这里采用的是竞赛中常用的BIT求法时间复杂度:O(Nlog⁡N)O(N\log N)O(NlogN)空间复杂度:O(N)O(N)O(N)Codeclass Solution {public: static const int maxn = 5e4 + 7; int lim,bit[maxn];

2021-03-01 21:45:47 91

原创 剑指 Offer 49. 丑数(小根堆)

Description我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。111是丑数nnn 不超过169016901690Solution因为要求从小到大的第n个丑数,所以我们采用小根堆,每次弹出当前最小的丑数,并把它的2/3/5倍插入小根堆即可注意还需要判重(set)Codeclass Solution {public: typedef long long ll; set<ll>s; c

2021-03-01 21:23:39 85

原创 剑指 Offer 52. 两个链表的第一个公共节点(LCA)

Description输入两个链表,找出它们的第一个公共节点。若不存在则返回NULL要求时间复杂度O(N), 空间复杂度O(1)Solution有点类似寻找LCA,故可借用朴素求LCA的思想,先把两个节点拉到同一深度,再同时向树根跳,第一次相遇的节点就是LCA。因此,本质上我们只需要预先求出两个链表长度的差值,再按照求LCA的方法即可。Code/** * Definition for singly-linked list. * struct ListNode { * int va

2021-02-24 01:07:31 73

原创 剑指 Offer 31. 栈的压入、弹出序列(思维)

DescriptionSolution若当前弹出的为x,那压栈队列中x之前的元素肯定已经被压过栈了基于这一点,容易发现:对于当前弹出序列的某一元素x, 若x比之前的弹出序列中在压栈序列中下标最大的元素下标还要大,那此次弹出合法若小于,且当前栈顶元素不等于x,则不合法,反之则合法我们只需要维护当前弹出序列元素在压栈序列中下标最大的元素的下标,并同时维护一个栈即可。时间复杂度:O(N)空间复杂度:O(N)Codeclass Solution {public: static con

2021-02-24 00:05:50 65

原创 剑指 Offer 30. 包含min函数的栈(单调栈)

Description定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。Solution光靠一个栈必然是无法实现O(1)查询min的,故我们考虑再加一个栈在维护一个正常的栈sta1的同时,维护一个非减的栈sta2(top是最小值之一)每次查询min的值时即为栈sta2顶的值为什么这样是正确的?假设当前需要push的值为x, 而sta2栈顶的值为y:若x > y,按照我们的设计,x不需要压入

2021-02-19 22:28:35 72

原创 剑指 Offer 28. 对称的二叉树(二叉树的镜像)

DescriptionSolution二叉树和它的镜像,实际上就是在层序遍历中每一层是左儿子优先还是右儿子优先的区别实现上,我们这两种遍历方法同时进行,若每次遍历到的节点都相同,则证明一颗二叉树是对称的时间复杂度:O(N)O(N)O(N)空间复杂度:O(N)O(N)O(N)Code/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; *

2021-02-19 21:17:30 64

原创 Leetcode 1004. 最大连续1的个数 III (双指针)

DescriptionSolution显然满足双指针中的单调性,即左指针+1的情况下,右指针(非严格)递增Codeclass Solution {public: int longestOnes(vector<int>& A, int K) { int l = 0, r = 0, res = 0; int cnt = K, n = A.size(); if(!K) { int tmp = 0;

2021-02-19 21:11:09 62

原创 Leetcode 995. K 连续位的最小翻转次数(贪心 + 双向队列)

DescriptionSolution观察发现,当从头开始处理到第 iii 位(前面的位数都为111)时, 若该位(在考虑被之前的翻转所影响的情况下)为 000,则必须翻转,且是以从第 iii 位开始向后K个长度的翻转(因为前面的位数都为111了,再翻转它们没有任何意义),所以我们可以贪心的进行翻转操作,即可满足最少次数的要求。实现上,采用双端队列的方式,动态维护能影响到当前位的所有翻转,根据现存翻转个数来判断该位的当前值(奇数个则取反,偶数个不变)时间复杂度 O(N)O(N)O(N)空间复杂度

2021-02-18 23:35:14 130

原创 剑指 Offer 41. 数据流中的中位数(大根堆+小根堆)

DescriptionSolution经典问题,用一个大根堆和一个小根堆来维护数据流的中位数,稍微手推一下即可Hint priority_queue<int,vector<int>,greater<int> >q2;//小根堆 priority_queue<int,vector<int>,less<int> >q1;//大根堆Codeclass MedianFinder {public: /**

2021-02-11 00:45:54 131 1

原创 剑指 Offer 35. 复杂链表的复制(Map)

DescriptionSolution存在两种拷贝:深拷贝和浅拷贝深拷贝主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。浅拷贝主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。而本题需要我们用深拷贝来复制该复杂链表,若每个节点只有一个next指针指向下一个节点,则只需要顺序遍历一遍待拷贝链表,同时复制一份即可;但这里还有一个random指针,所有我们需要同时建立原链表和新链表内存地址的对

2021-02-10 22:41:36 80

原创 Leetcode 1423. 可获得的最大点数(前缀和)

DescriptionSolution最终的方案一定是前缀+后缀,故 O(N)O(N)O(N)前缀和枚举即可Codeclass Solution {public: int maxScore(vector<int>& cardPoints, int k) { int sz = cardPoints.size(); vector<int>sum(sz); for(int i = 0;i < sz;++i)

2021-02-10 22:19:38 106

原创 Leetcode 567. 字符串的排列(双指针)

DescriptionSolution双指针 + check(), 复杂度O(32∗N)O(32*N)O(32∗N)Codeclass Solution {public: inline bool check(int *sum) { for(int i = 0;i < 26;++i) { if(sum[i] != 0) return false; }return true; } bool checkInclus

2021-02-10 22:15:46 77

原创 剑指 Offer 64. 求1+2+…+n (二进制)

DescriptionSolution第一眼觉得有点离谱,啥都不让用;突然想到一种只用加减和移位运算符来模拟乘法的方法,核心思想类似快速乘(龟速乘),将乘数进行二进制差分,对被除数进行移位后再相加。Codeclass Solution {public: typedef long long ll; ll mul(ll a,ll b) { ll res = 0, cnt = 0; res += ((a << cnt) & ((b&a

2021-02-05 23:08:47 87

原创 Leetcode 424. 替换后的最长重复字符 (双指针)

DescriptionSolution双指针Codeclass Solution {public: inline int MAX(int a,int b) {return a > b ? a : b;} int get_mx(int *sum) { int mx = 0; for(int i = 0;i < 26;++i) mx = MAX(mx, sum[i]); return mx; } int ch

2021-02-03 00:09:20 85

原创 Leetcode 1579. 保证图可完全遍历(思维 + 生成树)

DescriptionSolution首先注意到本题中的“完全遍历”概念本质上就是某人能走的边集为原图的一颗生成树故我们可以借鉴生成树算法的思想:避圈法(也就是kruskal的核心思想)再做思考,可删除的边分为两类,一类是某人独有的边,一类是二人共有的若我们删除某人独有的边,在不影响它本身的“完全遍历”性质的前提下,对另一个人的该性质无影响所以我们若要删除尽可能多的边,就应该优先删除独有边,再删除共有边本题一个不可忽视的条件所有元组 (typei, ui, vi) 互不相同该条件说明

2021-01-27 02:37:00 158

原创 Leetcode 25. K 个一组翻转链表 (模拟)

DescriptionSolution题目要求: 常数额外空间 && 实际上的节点交换先遍历一遍链表获取链表长度,再通过一次遍历进行节点交换第二次遍历时, 将链表按 k 个一组分组, 记录下每组的第一个和最后一个本质上就是把组内节点倒过来, 把前一组的第一个节点指向该组最后一个节点即可具体实现细节见代码时间复杂度:O(N)O(N)O(N)空间复杂度:O(1)O(1)O(1)Code/** * Definition for singly-linked list. *

2021-01-25 21:26:29 61

原创 Leetcode 1691. 堆叠长方体的最大高度(拓扑排序 + DP)

DescriptionSolution一个立方体可以任意翻转, 我们可以当成多个不同的立方体看待。问题转化为:有最多N*6个立方体, 最高能垒多高考虑DP[i], 第i个立方体放在最上面时的最大高度, 发现当前的状态是由所有可以垒在其下面的立方体转移过来的,所以我们考虑一边拓扑排序一边DPCodeclass Solution {public: #define N 202 struct cube{ int a,b,c; }; vector<

2020-12-24 23:44:34 239

原创 Leetcode 周赛#220 D. 检查边长度限制的路径是否存在 (并查集+离线)

DescriptionSolution将询问和边集按照边权从小到大排序后, 每次将比当前询问的lim小的边加入并查集中, 再判断此时两点是否连通即可Codeclass Solution {public: #define maxn 100005 int fa[maxn]; int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);} struct node{ int u,v,lim;

2020-12-24 10:34:50 74

原创 Leetcode 135. 分发糖果 (拓扑排序)

DescriptionSolution以孩子间的关系建单向边,每个点在拓扑排序中的层数之和即为答案Hint评分相同的孩子需要建双向边Codeclass Solution {public: #define maxn 200005 int d[maxn]; vector<int>edge[maxn]; inline void add(int u,int v) { edge[u].push_back(v); d[v]++;

2020-12-24 10:29:28 95 1

原创 Codeforces 1450D. Rating Compression (二分 + 单调栈)

DescriptionSolution猜想:假如满足条件的k的最小值(除1以外) 为 x, 那么大于等于x的k值都满足条件证明:待补用单调栈check的二分来找到这个最小值x时间复杂度:O(N∗log⁡N)O(N * \log N)O(N∗logN)Codeconst ll inf = 2e18 + 7;const int maxn = 3e5 + 7;int n, a[maxn];int head, tail,que[maxn];bool vis[maxn];bool check

2020-12-09 17:43:52 224

原创 Leetcode 842. 将数组拆分成斐波那契序列(模拟)

DescriptionSolution当类Fibonacci数列的前两项确定时,整个序列便确定了, 故我们只需要枚举前两项,在check一下是否合法即可小模拟Codeclass Solution {public: #define inf 0x3f3f3f3f int toint(string s) { if(s.size() > 10) return -1; long long res = 0; for(int i = 0;

2020-12-09 15:18:39 62

原创 Leetcode 621. 任务调度器(贪心)

DescriptionSolution先统计一下不同种类的任务出现次数, 在任意时刻,当前剩余次数最多的任务的优先级最高故可贪心的选取当前剩余个数最多的任务(“长作业优先" )Codeclass Solution {public: int leastInterval(vector<char>& tasks, int n) { int num[26];memset(num,0,sizeof(num)); int sz = tasks.s

2020-12-05 21:33:49 180

原创 2020 Jiangsu CPC H. Happy Morse Code(DP)

DescriptionExampleinput34 2a 01b 1001104 4a 01b 10c 01d 011001104 2a 1b 100110outputhappymorsecodepuppymousecat 3nononoSolution很明显的dp[i][j]:dp[i][j]:dp[i][j]: 前i位以第j个字母结尾的方案数这题的答案需要mod128,所以当结果为1时,不一定表示方案唯一。可以再开一个dp数组,记录某个dp状态是否存在

2020-12-05 13:59:08 332

原创 2020 Jiangsu CPC C. Cats(二叉树模拟)

DescriptionExamplesinput1output1input3output1 2 3Solution我们发现1最多出现一次,2最多出现2次,3最多4次…,显然i最多出现(1<<(i-1))次。我们构建一颗满二叉树,每一层的权值都为层数,以中序遍历方式依次取数,直到取到N个数为止Code#include <bits/stdc++.h>using namespace std;typedef long long ll;const int m

2020-12-05 13:06:22 239

原创 Leetcode 659. 分割数组为连续子序列(贪心)

DescriptionSolution分割出来的子序列需要尽可能的长,所以我们对于每个数,都贪心的放入目前放入的最短的子序列即可采用离散化+优先队列实现时间复杂度O(N∗log⁡N)O(N* \log N)O(N∗logN)Codeclass Solution {public: int mp[3*10007]; priority_queue<int,vector<int>,greater<int> >q[3*10007]; bool

2020-12-05 10:30:25 136

原创 Codeforces 1455C. Ping-pong(博弈)

DescriptionExampleinput31 12 11 7output0 11 10 7Solution两人轮流打乒乓球,因为存在放弃接球和上轮胜者必须发球的设定,所以后手占有主导权。题目要求每人的决策得先满足自己的胜场最多,对手的胜场最少的最优性。后手若一直让球直到对方最后一个球发出来时再开始接球,则能满足自己胜场最多,对方胜场最少而先手因为要先发球,所以本质上完全被后手所主导,自己毫无决策空间因此,先手只能先连赢x-1场后,后手开始连赢y场,然后游戏结束Cod

2020-12-02 23:17:31 1347 9

原创 Codeforces 1455B. Jumps(思维)

DescriptionExampleinput512345output13234Solution可以发现若每次操作都跳i的距离,最终的距离是等差数列之和;而显然我们不想让-1的操作次数过多,所以尽量先以等差数列跳到第一次 >= x 的位置,设为p若p == x,则直接出答案,若p > x, 则考虑将之前的若干次跳跃修改为-1操作,使得p -= (p - x)每修改一次操作 i 为 -1 对答案的贡献为 -(i+1),我们发现贡献是从-2开始连续的,并且只需

2020-12-02 23:08:43 234

原创 Codeforces 1455A. Strange Functions(思维)

DescriptionExampleinput5437998244353100000000712345678901337426966631415output1291026Solutiong(x)的分母部分就是将x的后缀0去掉(若存在)设x位数为k,若x有后缀0,g(x)的结果为k位最小值(100…),否则为1所以对于x的不同取值下,相同位数的x贡献为1(因为g(x)=1的情况与1位下的贡献重复),因此答案就为n的位数Code#include <bits/std

2020-12-02 22:59:46 228

原创 Codeforces 1457D. XOR-gun(二进制+思维)

DescriptionSolution设原始数组为aaa, 设bib_ibi​ 为aia_iai​ 的二进制位数若存在一个 iii,满足 bi−1=bi=bi+1b_{i-1} = b_{i} = b_{i+1}bi−1​=bi​=bi+1​,则我们只需要将后两个数异或,得到的数一定比 ai−1a_{i-1}ai−1​小(因为最高位变成0了)若这样的 iii 不存在,则原始数组的长度一定不超过 2*30 = 60,我们暴力计算 n≤60n \leq 60n≤60 的情况:最后的答案数组一定存在两

2020-11-30 21:54:45 171

原创 Codeforces 1457C. Bouncing Ball(DP)

DescriptionSolution先用dp预处理出以i为起点,以k为步长的路上会踩到几个砖块,以及有多少个格子然后枚举起点,更新答案Code#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1e5 + 7;int dp[maxn];int num[maxn];int a[maxn];void init(int n) { for(int i = 1

2020-11-30 21:43:43 134

原创 LeetCode 767. 重构字符串(思维+构造)

题目链接DescriptionSolution先将S串中出现的不同字母计数,设出现次数最多的字母出现了x次容易发现当x - 1 > S.size() - x 时,不存在答案;其他情况下答案一定存在考虑特殊构造:我们开辟一个列数为x的矩阵,按照字母出现次数顺序依次一行行填入因为是按照字母出现次数从大到小的顺序填字母,所以必然不可能存在同一种字母在列中相邻(1)最后按照列从小到大的顺序依次将每列的字母按照行从小到大的顺序放入答案中因为(1)的性质存在,所以答案字符串中一定不存在相邻两个字

2020-11-30 20:39:44 86

原创 2020 ICPC Asia Taipei-Hsinchu Site M. Keystroke(模拟)

DescriptionSolution模拟所有情况Code#include <bits/stdc++.h>using namespace std;int main(int argc, char const *argv[]){ int T;scanf("%d",&T); while(T--) { int m,n;scanf("%d %d",&m,&n); bool r[4], c[4]; clr(r,false);clr(c,false);

2020-11-25 21:38:29 373

原创 2020 ICPC Asia Taipei-Hsinchu Site H. Optimization for UltraNet(二分+最小生成树)

DescriptionSolution首先意识到这是一个最小生成树问题,但需要先满足所选边权值最小值最大,所以我们可以二分这个最小值,再用kruskal来check是否能成树然而最后需要计算任意两点路径上最小边权的和,貌似可以暴力水过去Code#include <bits/stdc++.h>using namespace std;#define pb push_backtypedef long long ll;const ll inf=1e18+10;const int m

2020-11-25 21:35:28 449 3

原创 2020 ICPC Asia Taipei-Hsinchu Site B. Make Numbers(模拟)

DescriptionSolution小模拟(ex)Code#include <bits/stdc++.h>using namespace std;#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define lc rt<<1#define rc rt<<1|1#define fi first#define se secondconst int mac=1e6+1

2020-11-25 21:30:31 361

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除