线段树
线段树($\tt Segment\ Tree$)最好用的数据结构,没有之一。
他可以以 $\log_2{n}$ 的复杂度处理区间和,区间最值,单点修改,区间修改等操作,也是非常的好用,有一些题目你可以直接上一个线段树,然后以比正解略劣的解法过掉。
思想维护一棵树,父亲区间被两个儿子平分,直到分到区间只剩下一个元素(叶子)
假如,我们现在有个 $a$ 数组,要使用线段树完成一些问题。
a[] = {[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]}建成线段树就是这样的:
之后,我们只要是进行单点的操作,就可以顺着叶子把一路上的东西都修改掉,而且由于每次一个点只被分成 $2$ 个儿子,树的层数是 $log_2 n$ 复杂度也有保障。
基本结构想要用数组存储一个上面的线段树,我们首先是要考虑,节点个数。数一数,发现上图一共有 $33$ 个点。经过长达 114514s 的思考,发现刚好是 $2 n - 1$ 。这难道是巧合吗?显然不是。可以给出如下证明:
叶节点数量
非叶子数量
总节点数量
二叉树效果图
1
0
1
2
1
3
...
517编程7段第五课T2
大秦为您打开题目传送门(3/1 题目大意题目的表述十分清楚,他就是让你求字典序最小的最长上升子序列,如果不存在输出 orz 。
注:在某人jdt1010的提示下发现不存在的情况是当 $n=0$ 的时候分值为两分多一点。
3/2 解题思路方法1:$dp[i]$ 表示以 $i$ 结尾的最长上升子序列长度我们阅读题目发现,这道题 $n$ 的数据范围非常大,传统的 $O(n^2)$ 算法肯定是用不了。所以开始思考换一种思路。由于题目数据范围是 $n\le 10^5$ ,所以不难想到使用 $O(n)$ 或者 $O(n\log n)$ 的算法。
我们开始思考:对于一个上升子序列,显然其结尾元素越小,越有利于在后面接其他的元素,也就越可能变得更长。所以,我们新建立一个 $st$ 数组,表示以 $i$ 结尾的最长上升子序列的结尾最小值,显然 $st$ 数组严格单调递增。那么我们实际上就只需要维护这个 $st$ 数组,从而去求出 $dp$ 值。
那么问题就变成了:如何维护这个 $st$ 数组呢?
如果这个 $a[i]$ 直接可以接到我们的LIS后面,那么就直接放到 $st$ 数组后面。
否则,就把 $ ...
洛谷P1990
大秦为您打开题目传送门(3/1 题目大意题目的表述十分清楚,他就是让你用竖着两个方块和 L 形的方块填满一个长 $n$,宽 $2$ 的长方形。方块可以旋转,如下图
1234 ___ ___ 方块2(反)* ______ /__/\ 方块1(横)* ______ /__/__ /__/__/\/__/\/ /__/__/\ /__/__/\ \_/__/\/\__\/ *方块1(竖) \__\__\/ \__\__\/ *方块2(正) \__\/ *此图大大滴形象
3/2 解题思路我们一拿到这道题,读完以后,显而易见的,这是一个编程题递推题。那么一开始我们大都会像下面这样推
设 $dp[i]$ 表示铺满前 $i$ 列的方案数。然后,自己枚举出 $dp[1]=1, dp[2]=2, dp[3]=5,dp[4]=11$ 。之后呢,又推出 $\tt DP$ 方程是 $dp[i]=dp[i-1]+dp[i-2]+dp[i-3 ...
【转】堕落的天蓝色天使
eb44ce4cc1f4aef4a1743005f1d61db38493313ec0cc8411555ac81a8eefebed5c5a6fff6ab506cd748a43244ee95f6a70d5d8d9e5ea8984c657960957aa19e5ea87afd86e705667ae12cb13a7a2934d8c35147cbb2248f694d85fc33eb0a43b036255dc28b1275e7691c051912e370281c1527ef7f8af3400428d6b5801e4d4c0d930dd0a6ff5fa2dae8a81a9e7cd49e709bc303a4c6605fb050d057f787a5593407724b1157c9c0ef698beac96cd37d6b13c1f4eb459ed65382f6c2a9ce65f386db59474d1ea46aa82b4f67c416f686993cb6c8b4ada83d094d2969b51b174038427fb87510510b06d1a4f06b147d73a605a0b2537d3965 ...
【转】破碎的白金色爱恋
bbbf624166adc60d21b5c93a5386e92f3067258d7f09cbf7b9a987184e9d5018650b55d1ad71393fb700b878d1ad94fe01f0032e81f0fb6e3b36c0dfbfeb7b4e11260e2bac987289989dddb01fa74360e590575ab6e224e1cbfe3939e59b5011eb5b54c49cd53875adac180044b57f945e58b0dc45087aeee4e1b822bc106c58795e2010532881ff7d095788ba988b46b5c80d84a49a11f075555b3a282a98dd274c090a23b8851d9311ec1e0576e8f75df049fd94a8f431567c6763f7b84c614fbb8c5ceaefaf8d7ecbfaa26ef2821018b0a2b190acab53acff7864520545e2194b3affcd061521d4071acece137f32945e7d5c924257515 ...
排序算法
排序在我们的生活中很常见啊(((
基础知识
排序的稳定性:两个相等元素在排序之后相对位置没有变化(比如A=B,A在B的左边,排完序后A还在B的左边)
基本上没有别的了((((不要说你连什么是时间复杂度和空间复杂度都不知道
冒泡排序冒泡排序,这是一个效率极低的排序算法,他是通过一个一个数比较大小,然后交换位置使数组有序的算法,因为数字在交换过程中像泡泡,所以叫冒泡排序。
123456789for(int i=1; i<=n; i++){ for(int j=i+1; j<=n; j++){ if(a[i]>a[j]) swap(a[i], a[j]); }}for(nit i=1; i<=n; i++){ printf("%d ", a[i]);}
显而易见,这是 $O(n^2)$ 的排序算法
计数排序相比之下,计数排序是一个比较好的选择(
对于数字比较小的情况下(数字不可以小于零),我们可以统计每个数字的个数,然后按数字输出。
123456789101112int cnt[1 ...
高精度算法
庞大的数字,从更加庞大的视角来看呢?—— 高精度
总体思想因为数据结构的局限性,int 可以存下 $9$ 位数,long long 可以存下 $20$ 位数,__int128 可以存下 $39$ 位数 ,之后我们就只能使用更大的存储方式,高精度就是使用数组存储的数据结构。
其实现方式就是,使用字符串输入,数组模拟计算方式。
实现输入由于没有足够大的数据类型去装下及其大的整数,所以,我们可以使用字符串读入。由于数字比较大,使用 string 可能会出现问题,所以使用 char 数组。(高精乘复杂度 $O(n^2)$ ,所以涉及到高精乘的 $n$ 不会特别大)
1234567int a[2010];string s;cin>>s;for(int i=0, len=s.length(); i<len; i++){ a[i]=s[len-i-1];//为了方便进位,我们把数字倒着存储}
计算接下来,我们预处理好两个参与运算的数字的数组后,我们要开始模拟运算。
我们来思考,在我们小学刚刚学加减乘除时,使用的方法是什么((
加法:按位加法,然后处理进 ...
关于hexo访问tag页面的问题
可能是版本问题哦,输入 hexo -v 看看是不是版本7.0.0,记得改成版本6.3.0。
Hello everyone
在大家的帮助下,本蒟蒻的hexo博客也算勉强顺利搭建完成!
【花雨】【死亡笔记】惩罚游戏
“打个赌吗,月君?”
夜神月没有抬头,他已经习惯L突然闯入。说什么闯入呢,囚犯有什么隐私可言?他只能自嘲一笑:“赌什么呢?还剩什么可以赌的?”
“就赌……”L走得更近了些,伸出手抬起对方的头。灯光大概很晃眼吧,前基拉眯起了眼睛,曾经冷酷的眼神带着茫然,才过去多久啊,已经很难相信这家伙是那个基拉了。那个微笑完美无缺、蛇蝎心肠、不可一世、自诩为神的屠杀犯基拉。“赌你的未来和我的性命。”
“呵,难不成你输了就心甘情愿地放弃自己的性命,把我放出去?”月像听到什么好笑的事情一样,忍不住笑了起来。笑声越来越大,L松开了手,任由对方弯下腰去。“我说……”夜神月重新抬起头,伸手擦了擦眼角笑出的泪水,“就你这么胆小的家伙?”
L面无表情,毫不在意对方如何表现。到现在他也分不清这家伙是自暴自弃还是在用激将法了,但反正这是他已经决定的事情。
“没错,就赌这个。”
“哈哈哈哈哈——”月戛然止住了笑,不可思议地瞪大眼睛,“你说什么?”
“月君的心气已经完全消失了吗?”L评估似地咬着拇指,盯着夜神月——月厌恶这个表情,像是观察小白鼠一样的无情的表情,甚至连高高在上都算不上,因为根本连同类都不是。但他不是——不是一 ...