自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(39)
  • 收藏
  • 关注

原创 codeforces round 956 div2

思路:我们现在思考一个这样的问题:交换相距任意长度的元素是否都可以通过交换相邻元素实现,答案是一定的,自己模拟一下很容易就可以证明。对于一组没有重复元素的序列,我们每一次交换相邻元素都会让该数组的逆序对数量 + 1或者 - 1也就是说,我们每一次操作都会使得ab两个数组逆序对数量的差值不变,或者减2,或者加2,如果我们可以让ab两个数组的逆序对数量相同,那么ab数组就可以相互转换,也就是如果ab逆序对数量和为偶数,数据就是合法的。思路:贪心的从第一行第一列开始构造出和b一样的数组,如果构造完后a!

2024-07-09 11:11:50 306

原创 codeforces round 953 div2

思路:不难发现,假设最开始我们的答案permutation与原有序permutation一致,此时如果交换相邻元素会使得最终结果add 2如果岔开一个交换会使得结果add 4...类推后发现交换i,j号元素会使得结果add 2 * (j - i)。因此在构造序列时,我们可以先从当前可以选择交换的最大值的开始构造,即先交换可以交换的最远距离,若第一次交换i,j那么第二次的交换区间就变成了在(i +1)到(j - 1)内重复第一次交换的操作。注意,这里只是感性的理解,并不是理性的证明。

2024-06-18 10:44:37 253

原创 codeforce round951 div2

思路:对原操作进行化简,实际上就是把前p个字符翻转,并且接到原字符串的后面,则此时我们的答案串实际上是已知的如果第p个字符是1,那么答案串就是以1结尾的k pop串,反之则是以0。结尾的k pop串,既然答案已知我们遍考虑枚举p,之后在o1内用哈希字符串比较。由于分数的精度不好计算,因此考虑乘上所有k的lcm。这个是判断条件,如果成立给每个1/k乘上lcm即可。思路:guess题,就是求两个数的lowbit。即 lcm * sigma 1/k < lcm。变形后有sigma 1/k < 1。

2024-06-10 18:34:17 282

原创 codeforces round950 div3

思路:维护两个点集,第一个点集表示最开始a[i]与b[i]不同时b的值,第二个点集维护在进行操作时,操作到不在b[i]中的点,也就是对答案一定没有贡献的bad点。在操作时,如果操作的数值在第一个点集中,这时候把该点集中的点erase掉,如果出现了bad点,则加入第二个点集中,如果出现了在b中的点,并且第一个点集中没有了,则把bad点集清零(假设当前操作在为b[i],前面所有的bad点都可以操作在这个位置上,反正最后这个点还会变成b[i])最后如果两个点集都被清空了,则说明合法。

2024-06-04 20:21:18 353

原创 codeforces round 949 div2

对于这种解法的正确性可以考虑一颗二叉树(父节点u 左子节点2u 右子节点2u + 1),有两个节点,两个节点不断除2最终一定会到他们的lca上.从x自增到y,发现x,y最左边两位是相等的,因此这两位相等的位只有为1时才会对答案产生贡献,这两位其他位会从小的不断自增到大的,因此这些位肯定会出现1,因此答案就是从左向右拆位直到找到第一个不同的位,这之前只有1对答案有贡献,这之后都对答案有贡献。思路:实际上就是求一个区间内的or值,区间为max(0, n - m), n + m。当然也可以直接输出_lg(x)

2024-06-03 17:45:22 441

原创 codeforces round947 div1 + div2

思路:任取数组中连续三个元素,根据定义,这三个元素最后会被变成这三个元素中的中位数a。则此时存在两个连续的a。顺着连续的a向左右两侧,每次选择两个a以及相邻的一个元素进行操作,最终数组都会变成a。注意,当n=2时没有三元组,此时答案为两个数中的较小值。思路:sort一下数组去重,最小的元素肯定是答案之一,紧接着遍历数组,碰见第一个不能被最小数整除的将其加入答案集合,若碰见第三个不能被当前答案集合中任意一个数整除的数,则数组不合法。思路:可以想象原数组为一个环,如果在环中可以找到不降序列,则满足题意。

2024-05-26 17:17:07 233

原创 codeforces round946 div3

思路:分别考虑竖直方向水平方向,以水平方向为例,出现ew可以抵消,若最后剩下的e或者w为偶数个则合法,另外还要判断H,R是否执行了至少一条指令例如WE这个条件是非法的,原因是肯定有一个机器无法执行命令。这里代码写的很繁琐,写完比赛就结束了,抽时间改一下。思路:背包,dp[i]表示当前happy值为i,可以拥有的最大钱数,从大到小枚举是为了让状态转移时用已经搜过的状态转移,最开始把不可能的状态置负无穷dp[0]置0,这样搜出来的方案一定是可以实现的,dp时每个月记得加上工资。

2024-05-23 12:36:25 354

原创 codeforces round937 div4

这时候可以考虑状态压缩dp,用二进制数表示出所有状态,2^18并不是一个很大的数,不用担心mle的问题。我们往序列后添加歌曲的条件是添加的歌曲与序列最后的歌曲音乐类型与作者是否相同,因此可以给dp数组再加上一维,表示目前状态最后一个歌曲的编号,如果i号歌曲在01串对应的需要为0,并且该歌曲与末尾歌曲可以匹配,那么此时i与01串对应位置要置1,并且数组二维下标要变成i。注意,多次比较字符串的操作较慢,最后会t33,这里可以先对字符串进行预处理,或者把字符串映射成数字,第二种操作类似于离散化。

2024-05-22 15:22:50 227

原创 codeforces round944 div4

赛时一直想着排序了,由于最开始没注意到排序本身就是tle的,在写的过程中发现每次还要将首位元素删去,其实在这里应该想到堆的,但是我一点没往这里想,甚至还加了个数组idx表示当前的下标,第一次交发现越界了,原因是idx数组下标最大值是1e9 / 4,数组开大又会mle,甚至加了个离散化,最后提交上去果然tle,遂想到了堆,浪费不少时间。思路:把圆看成一条链 任选两点ab,再选两点cd,如果cd满足其中一点在区间ab内另一点在区间ab外,则两绳一定相交。不会处理精度...待补。思路:顺着题意写就行。

2024-05-14 11:12:26 288

原创 codeforces round943 div3

思路:这道题挺抽象的..相信很多人都能想到前缀和优化异或,然后就不知道怎么处理了...根据异或性质如果有五段分别为x x x x x由于x ^ x = 0, x ^ 0 = x,因此所有奇数数段都可以继续合并成3段(x ^ x ^ x = x | x | x),同样的,偶数数段可以继续合并成两段,因现在只需要判断是否可以找到合法的两段或者三段。思路:二分 + 字符串处理 字符串处理在check中比赛时忘了kmp怎么写了,写的暴力tle了....问题:为什么会爆long long?这两段代码有什么区别?

2024-05-07 16:06:59 370

原创 codeforces round 886 div4

problem:最开始处理的时候并没有考虑到最后建起的图可能不是连通的,也正因为可能存在多个图,边必须要加成无向边。思路:如果两个点有关系就在这两个点之间加一条无向边,最后再bfs扫图,判断是否存在冲突条件。思路:找到a + b a + c c + b中的最小值并判断是否大于10。问题:二分条件为sum <= c的代码仍然wa中...思路:找到长度不超过10的质量最大值对应人的编号。思路:找到每个点的约数并判断该约数是否可以达到。思路:排序后用n减去最长的平衡的一段。带权并查集 差分约束待补....

2024-05-04 17:11:51 285

原创 code forces round898 div4

(如果B位于字符串开头,那么可以认为这个位置的B可以向左移动0个位置,字符串末尾的B同理,因此这种思考方式是合法的)用于B只能在A上移动,因此最终获得的硬币数量是A的总数减去任意一段A的数量,显然,最大值就是让sum A - A数量最小的一段。那么如何处理呢,维护一个start指针,表示h数组的首位置紧接着枚举指针i表示start之后的位置,依次判断start指向的元素是否可以整除i指向的元素,如果可以整除start到i之间的所有数加1,(这是差分可以处理的经典问题),反之则让start指向i...

2024-04-28 23:19:24 300

原创 codeforces round929 div3

问题:在最后判断r与r + 1哪个更加合适的时候,最开始写的判断条件一直是a1

2024-04-25 11:26:24 921 1

原创 codeforces round933 div3

这明显是一个线性dp,设dp[i]表示第i个格子的价值的最小值,并且dp[i]可以从前i - d - 2 ~ i - 1个状态中的最小值转移过来,求固定长度的区间中的最值,这道题就变成了单调队列板子题...问题:在取模操作求可能持有球的球员过程中,由于球员是1到7的,因此可以让第一个持球的球员本身编号 - 1这样的取模操作的含义就变成了传球后持球球员距离0的距离,最后输出的时候再+ 1就输出了编号。代码也可以写成一个循环,如果碰见子串map, pie ans ++ mapie ans --

2024-04-22 19:46:25 360 1

原创 codeforces round918 div4

.’由于题目所给字符串合法,因此CVC后一定是C 先找出所有的类似CVCC的结构并在第二个C上做标记这个标记表示辅元辅音节,第二次遍历时如果碰见V如果这个V后面的C没有被标记则说明这里的V是辅元结构应该标记。如果存在 s奇1 - s奇2 = s偶1 - s偶2 == s奇1 - s偶1 = s奇2 - s偶2 则满足题意 可以用map存所有的s奇 - s偶 时间复杂度O(n * log2n)问题:在离散化二分时,由于要把离散化内容控制在1到a.size()范围内,代码一直报错,明天补题....

2024-04-19 21:30:12 249

原创 codeforces round938 div3

由于在维护时只要是在map中的元素都会对答案产生贡献,因此窗口中不会限制有贡献元素的数量,所以窗口中可能会出现有1, 1, 1此时只能算两个1)思路:可以发现,只有4会影响从右向左数第三位数位中1的数量,因此这个可以拉出来单独讨论,剩下的第一位数位中1的数量会被1与3影响,第二位数位中1的数量会被2与3影响因此1,2数位可以用动态规划来求dp[i][j][k]表示1,2,3卡片分别有ijk张时bob赢的最大次数,最后的答案是两部分相加。思路:暴力枚举可能的长度 + 贪心差分判断这个长度是否可行。

2024-04-17 10:20:28 615

原创 codeforcese round 957 div3

思路:对于每个数x拆成x个1要x - 1步,合并要x步,因此一个数x的贡献就是2 * x - 1。思路:要尽可能的往木头上跳,如果不能跳到木板上,那么就按跳的最大距离跳到水中,游到下一个木板,并在这一段游泳的过程中判断是否遇到鳄鱼,以及游泳距离。怎么这两段处理交叉,或者不交叉的情况,开个st数组对序列判重,先输出n 到 k,再输出没有被判重的代码块,再从1到m中输出没有被输出的。没申请留校,恰好碰见宿管巡楼,把隔壁寝没申请的留校的宿舍给一锅端了,吓得我直接关灯关电脑,再加上nt的真人验证,要掉大分了。

2024-07-20 16:19:45 303

原创 atcoder abc 360

第一个二分找到向左移动的蚂蚁中第一个坐标大于等于x蚂蚁的坐标,如果找不到,则说明x不会对答案有贡献,直接continue,反之如果找到了,那么开始第二个二分,第二个二分查找的是最后一个小于等于 x蚂蚁的坐标 y 加上 2 * T的蚂蚁。思路:三层循环,第一层循环枚举w,第二层循环枚举w个字母中的第i位,第三层循环枚举被划分后的每个字符串的第i位。思路:输出所有装有至少2个物品的盒子中除了最大质量的物品其余物品的质量和。将向左移动的蚂蚁视作静止,同时向右移动的蚂蚁每个单位时间移动2个单位长度。

2024-07-01 10:06:09 345

原创 atcoder abc 359

注意到每次竖直方向上走一个可以在水平方向上多增加一个偏移量,因此只要先解决竖直方向,然后可以得到一个水平方向的最大范围,只要水平坐标在这个范围内就不用计算水平方向上的花费,反之计算差值除2即可。j与k之间又有什么联系呢,让他们错开一位上下摆放,就可以发现除了第一位和最后一位,其他位都是相同的。再加一维索引dp[i][j]表示以下标i开头的字符串且状态为j的所有good string 的数量。思路:找出所有a[i - 1]与a[i + 1]相等的pair。则有dp[i][j] += dp[i - 1][k]

2024-06-26 17:22:30 250 2

原创 atcoder abc 358

1 字符串比较是浪费时间时间,因此可以考虑优先处理下字符串,这里的做法是状态压缩,o代表二进制的1,x代表2进制的0,两个摊位的爆米花口味是a | b。思路:堆, 排序, 双指针,贪心,平衡树都可以做。思路:记录下第 i-1个人买完票的时间now,更新now 为max t[i], now后now + a 输出now。3 排列组合优化 这里选的摊位并没有明确的顺序,因此先选a和先选b是一样的,可以在dfs中记录一个start。思路:注意到n很小,考虑爆搜,现在思考一个问题,如何把时间尽可能的压缩。

2024-06-22 16:45:02 451

原创 GDCPC

接着开始寻找遍历顺序,顺着上面的思想推个公式假设节点x有n颗子树,为了简化问题,这里n取2(其实是不会证n...一堆式子看着就头疼)分别为1 2设先计算1为最优解 则有 w[1] * 1 + w[2] * (_size[1] + 1) > w[2] * 1 + w[1] * (_size[2] + 1) 化简 w[2] * _size[1] > w[1] * _size[2]递推式子就出来了...只要在dfs时,对于每个u临边遍历完之后对其临边按照这个式子sort即可。例如一颗如图所示的树。

2024-06-20 10:29:34 207 2

原创 算法竞赛数论杂题

但是现在两端点都是不确定的,注意到 l <= k * g < (k + 1) * g <= r 注意到我们想要得到的gcd与k的乘积是不大于r的,因此这两个未知量的较小值是不大于sqrt(R)的,因此我们可以枚举较小值i,另一个值自然可以通过R / i得到 由于在循环中k * g <= r 是一定的,因此在判断方案是否合法时只需要判断左边界l是否满足即可。时间复杂度o(sqrt(R));显而易见,如果a = b x将会有无穷个,如果 a < b x将为0。因此k一定是(a - b)的一个因数。

2024-06-19 20:32:07 323

原创 atcoder abc357

思路:逆元,快速幂,对原式子变形后发现最后的结果实际上就是x 乘上一个等比数列,这是碰见的第一道逆元的题目,也明确了我对逆元的认识,由于 a / b % mod!= (a % mod/ b % mod) % mod,而直接除的话会造成精度丢失,因此我们可以把除法变成乘法,根据费马小定理如果b和p互质,那么b的逆元就等于b ^ p - 2 因此可以快速幂求逆元。思路:大小写转换,这里有个问题,为什么我的转换最后都变成数字了,先留个疑问。思路:前缀和,暴力,你想咋做就咋做。

2024-06-09 22:12:09 851 3

原创 atcoder abc 356

思路:注意到问题实际上把所有元素都做一遍比较,并且用大的数除小的数,因此最开始的思路是先sort,再用前缀和做,最后发现样例都没过去,发现前缀和会影响每个pair下去整的性质,例如3 / 2 + 3 / 2下去整 = 3 但是 s[3 + 3] / 2 = 3 并且找不到优化方法。思路:位运算,对m拆位后,对于m第i位的二进制数字x,只有x为1时对答案有贡献,于是问题变成了找到1 ~ n中所有第i位(m >> (i - 1) & 1 == 1)为1的1的总和。思路:暴力枚举,枚举后作比较。

2024-06-02 22:19:02 435

原创 atcoder abc 355

【代码】atcoder abc 355。

2024-05-26 17:21:50 294

原创 atcoder abc 354

思路:如果不输出元素下标的话,这道题就是lis板子题,但现在让输出所有可能是lis一部分的元素下标。思路:对A关键字排序后,考虑最后的结果C关键字应该是什么顺序,不难发现,最后C应该也是升序,若不是升序则仍然存在可以被丢掉的卡片。思路:对字符串数组排序, 本来还想着顺着字符串字典序的思路写个cmp函数,但是太懒,本着试一试的想法直接交了个sort,没想到ac了....cmp函数就是先比字符串长度,长度短的字典序小,如果长度相同就按顺序依次比较字符,字符越靠近a字典序越小...思路:前缀和,注意第0天是1。

2024-05-19 20:24:01 268

原创 atcoder agc 177

于是乎对边权只有两种可能的图进行bfs时,只要将边权大的放在队尾,把边权小的放在队头,就不会影响维护队列的这两个性质...思路:把图抽象成边权只有0和1的带权图,例如如果是从1,1走到n,n途径R可视为边权为0,途径B由于要把B变成P,因此B的边权视为1,于是这道题就变成了双端队列bfs的板子题...思路:贪心,尽可能让价格大的商品消耗掉面值大的硬币 注意:atcoder与cf不同,atcoder并不会将YES与Yes都储存在答案集合中。思路:贪心,顺着题意写就行..

2024-05-13 16:44:14 284

原创 z函数 扩展kmp

在计算z函数之前,要了解z box。对于每一个i都存在一个z box(z box == str[l ~ r]), 满足z box是str的一个前缀,并且i∈[l, r],还要满足r尽可能的大。对于str中的每个str[i] z函数计算的是str[i ~ j]的长度,也就是以str[i]为首的子字符串对于str lcp的长度。第一种情况是z[i - l + 1] < r - i + 1(不取等是为了满足r尽可能大这一性质) 因为前缀与z box相等,因此对于i位置的z[i] == z[i - l + 1]

2024-05-09 20:14:31 123 1

原创 算法日记 数组模拟链表

单链表只要创造两个数组,一个储存数据,另一个储存地址,理论上来讲就可以模拟链表。数组头插法模拟如图所示,头插法就是将插入节点与储存地址的数组建立联系,再改变左指针指向。1:初始化。让头结点head=-1表示NULL,并且让idx=0。idx在此处存放要用到的下标,每用一次,idx++。2:建立联系。先储存数据。val[idx]=x。再建立联系。ne[idx]=head。若第一次插入,就表示ne[idx]此时=Null。3:改变指向。head=idx。最后idx++。这里可以理解为

2023-02-02 18:38:18 92 2

原创 算法日记 区间合并

1:适用范围将含有交集的区间合并。2:原理将区间的左端点排序后进行合并,合并时会遇见三种不同情况,处理时也要根据维护区间与遍历区间的关系来处理。情况1st(start)——————————ed(end)维护区间 ———— 遍历区间该遍历区间是维护区间的一个子集,因此合并后维护区间不会发生变化。情况2———————————— ———————————该情况维护区间的ed比遍历区间的e

2023-01-25 21:09:48 61

原创 算法日记 离散化

1适用情况:用于稀疏的数列处理。比如一段长度为100000000的区间,仅仅对其中较少元素做出处理,此时可用离散化。2 原理将目标区间上稀疏的元素排序使其拥有一定单调性后,将所有元素映射到另一个区间中,使得元素紧密排列。映射后可用二分法查找元素下标。alls.erase(a,b):去掉alls动态数组中a,b内的元素。alls.unique(a,b):将alls动态数组中a,b内元素排序后提取重复项并返回无重复元素排序的末尾的下标。二分后return r或return r+

2023-01-25 20:57:27 53

原创 算法日记day7高精度乘法除法

高精度乘法这里的高精度乘法是一个高精度数据A×一个低精度的数据b,我们将数据b看做为一个整体。这里的巧妙之处在于for循环的循环条件,这个循环条件在限制数组长度的同时,把最后t的进位也融合了进去。高精度除法与乘法一样,都是一个精度高的数据与一个精度低的数据的运算。除法运算要返回商和余数,因此在定义函数时,在return商C的同时还要引用(&)余数r。高精度除法在运算是也是唯一一个倒序运算的算式。除法和减法一样,要去前到导0。另外,reverse函数是一个改变数组顺序的函数,

2022-12-24 10:27:01 84

原创 算法日记day6高精度减法

高精度减法高精度减法中比较重要的一点就是判断A和B哪个大。这里采用的是bool函数,由于数被储存在数组里无法直接比较,因此通过比较size来比较大小。若AB的size不同,则return A.size()>B.size()这里表示若不等式成立,则return TRUE反之则FALSE。若size相同,则分别比较每一位上的数字。由于输入数据时是逆向输入的,因此比较时也应该逆向遍历比较,if(A[i]!=B[i])return A[i]>B[i]这里没有直接return是为了判断相等的情况,倘若

2022-12-23 13:07:39 93

原创 算法日记day5内含高精度+法以及stl

高精度加法本身是一种计算机模拟人列竖式计算的一种方式。图中用字符串输入,再将字符串变为数字后逆向输入进数组,目的是方便进位。auto会自动判定变量是什么类型,貌似效率也更高....vector是动态数组,数组的长度可以随时变化。使用动态数组要+头文件#include <vector> 动态数组定义方式是vector<数据类型>变量名例如vector<int>A 则A.size()就是动态数组A的长度。若要往A中加入元素,则A.push_back(a)表示把a

2022-12-22 13:08:41 57

原创 算法日记day4

数组的逆序直接上代码这种方法简单来说,就是在归并处理后,将我们需要的答案分成三个部分。部分一是mid以左,部分二是mid以右,部分三是left和right。归并的目的是让数从小到大排列,方便分析。从小到大排列后,指针j每移动一次left和right中逆序对的数目就等于res+=mid-i+1。虽然数组中数的顺序被改变,但是left和right中数的相对位置没有改变,在前面的依然在前面,在后面的依然在后面,因此不会对结果造成影响。而对于left部分或者right部分,就可以当做一个长度为mi

2022-12-21 16:26:56 56

原创 算法日记day3

阳了这么多天终于好了今天继续写日记。二分如果一组数,存在某种条件能把这组数一分为二,使得这个数组下标中点以左的数(不)满足该条件以右的数不满足该条件,那么此时就可以用二分处理。如此题,若给定数组12 2 3 3 43起始与角标3终止于4,并且mid=2.5=2因此答案应在mid+1,r中(闭区间)给定x为任意元素若mid所对应数>=x则答案在l到mid中此时只需令r=mid反之只需调整l令l=mid+1最后所剩的单元肯定是x(前提x存在于数组中)。另外,这样找到的x是

2022-12-20 22:22:17 83 2

原创 算法日记day2

归并排序:1选择下标通常选中间下标。int mid=l+r /2 2递归merge_sort(a,l,mid)merge_sort(a,mid+1,r) 3合并选择下标后设两个指针i,j分别向后移动i从0开始向后移动,j从mid+1开始向后移动。如果碰见a[i]>a[j]则tmp[k++]=a[i++]反之一样。当i走到mid或j走完时停止。此时i或j中可能有一个没有走完导致数组没有遍历完,让没

2022-12-14 21:16:20 65

原创 函数库,持续更新

iostreamswap函数,交换两个变量的值,可用于数组。cstdlib,ctime常常搭配使用,用作随机数srand(time(0))以秒为基准的随机数种子x=a+rand()%b;a,b为自然数 表示x的取值范围为a~a+b-1。cmathround常常用于c++中的四舍五入。printf(“%.2lf”,round(a*100)/100)表示a四舍五入到两位小数。如果头文件是stdio.h,就不需要用round,会自动四舍五入。pow(a,b)表示a的b次方

2022-12-13 22:43:24 73

原创 关于分治及其应用,持续更新

I:分治在排序中的应用这里的排序分为三个步骤:1:随机取值作为划分的标准,一般选用a[l],a[l+r/2],a[r],设为x。2:将数组分成>x和<x两部分。这里采用的方法是取了两个指针i和j,分别让这两个指针向中间走,直到两个指针相遇为止。因为函数中用的do while循环,进入循环后立刻i++或j--,因此在定义时应该让两个指针分别比最小下标少1,比最大下标多1。3:分别对两部分递归处理。函数递归,这里要考虑边界问题:

2022-12-13 22:29:53 67

空空如也

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

TA关注的人

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