- 博客(62)
- 问答 (1)
- 收藏
- 关注
原创 E. Fair Share
Problem - 1634E - Codeforces思路:先考虑什么情况的时候无解:显然,当某个数字的总数为奇数时必定无解,那么当每个数的总数是偶数时是否一定有解呢?每行一共有偶数个数每个数出现偶数次我们考虑建下面这样的二分图,每行看成一个点aia_iai,每行的数字和aia_iai连无向边。这个图显然存在欧拉回路。在欧拉回路中我们令以aia_iai为出点的数字分到RRR,以aia_iai为入点的分到LLL。我们这样就能保证每个数组中的分到L,RL,RL,R的数量是一样的。因为无
2022-03-04 23:04:33
212
原创 2021 ICPC Southeastern Europe Regional Contest C. Werewolves
传送门思路:考虑对每个颜色分别进行计算。如果该节点的颜色为当前计算的颜色,令 vali=1val_i = 1vali=1,否则vali=−1val_i = -1vali=−1。显然要使子树颜色相同的数量严格大于一半等价于这个子树和大于等于1。求一个子树中和大于等于1的方案数,我们可以树上背包。定义:dp1[u][s]dp_1[u][s]dp1[u][s]: 以u为根的子树,和为s(s≥1)s(s\geq 1)s(s≥1)的方案数。dp2[u][s]dp_2[u][s]dp2[u][s]:和为−
2022-03-02 23:33:00
755
原创 牛客 树的距离
传送门题意:有一颗有根树,根节点为1,赋有边权。现有m次询问,每次询问在x的子树中所有与x距离大于等于k的点与x的距离之和。思路1:x于子树中某节点的距离就是 该节点到根节点的距离 - x到根节点的距离。那么我们维护一下x子树中所有点到根节点的距离,求出所有距离大于等于k+d[x]k+d[x]k+d[x]的和sumsumsum,再求出点的个数cntcntcnt,答案就是sum−d[x]∗cnt。sum - d[x] * cnt。sum−d[x]∗cnt。显然主席树可行。这是一种在线的做法#includ
2021-08-25 16:04:59
267
原创 2021牛客暑期多校训练营9 E.Eyjafjalla
题意:求点权在[l,r][l,r][l,r]范围内最大连通块元素的数量,且必须包含x思路:根据越往靠进根节点温度越大这个性质,我们可以发现只要找到x向上最远能传染到的那个点,我们求那个点子树中点权满足[l,r][l, r][l,r]的数量就行了。找点根据单调性可以二分。线段合并:给每个点建立一颗权值线段树,边dfs边向上合并,这样dfs结束后u上的线段树维护的就是u子树的值域。这样写得保证在合并过程中不破坏子树线段树的结构,我们可以在合并的过程中再复制一个节点,不过这样空间的开销会增大一倍。时间复杂度
2021-08-19 10:06:57
187
原创 P4556 [Vani有约会]雨天的尾巴 (线段树合并 + 树上差分)
传送门题意:给一颗树,n个节点,m次操作。每次操作使u到v的路径上每个节点中颜色z的数量加1,最后询问每个节点中数量最多的颜色。思路:显然,我们得维护每个节点中颜色的最大值。那么我们给每个节点开一颗权值线段树,维护颜数量的最大值。现在关键是如何优化路径操作 —— 树上差分。关于树上差分的可以参考蓝书上的解释“根据差分序列的前缀和是原序列"这一原理,在树上可以进行类似的化简,其中"区间操作"对应为"路径操作”,“前缀和"对应为"子树和”。我们设u,v的lca为t,类似于数列上差分我们让u的z+1
2021-08-18 20:42:26
221
原创 Dima and Salad
传送门题意:有n个物品,每个物品有两种属性aia_iai,bib_ibi,要求最大的∑imai\sum_i^{m}a_i∑imai且∑imai/∑imbi=k\sum_i^{m}a_i/\sum_i^{m}b_i = k∑imai/∑imbi=k;思路:把式子整理一下:∑imai−k∗∑imbi=0\sum_i^{m}a_i-k*\sum_i^{m}b_i = 0∑imai−k∗∑imbi=0 我们把每个物品对答案的贡献转换为$...
2021-07-31 22:01:10
224
原创 Codeforces Round #735 (Div. 2) (A-D)
传送门A . 思路:对于一个很大的数,区间越大最小的数是越小的,他们的乘积也就越小,所以枚举相邻两个数就行了。#include<bits/stdc++.h>using namespace std; #define lsn (u << 1)#define rsn (u << 1 | 1)#define mid (l + r >> 1) typedef long long ll;typedef unsigned long long ull;
2021-07-30 11:32:41
181
1
原创 2021牛客暑期多校训练营3
B Black and white思路:通过观察我们发现,我们其实最多只用选n + m - 1个点就好了,其它的点对答案的贡献为0。那么我们不是贪心的选择这n+m-1个格子就好了?还有一个问题,我们不能让一个小正方形4个点全都被选。这里有这样一个技巧,把一个点(i, j) 拆分成两个不同的点Ai Bj,当我们选择把这个点涂黑时就给Ai,Bj连一条边。只有正方形4个点全选才会改变连通性(可以自己画一下),那么我们跑一次最小生成树就行了。#include<bits/stdc++.h>usin
2021-07-25 13:04:56
134
原创 Codeforces Round #656 (Div. 3) E. Directing Edges
传送门题意:一个图,给你n个顶点,m条边,m条边中有些是有向的,有些是无向的。现在要求你把无向的边全部变成有向的边,能否使图最终无环?思路:先只看有向边,若原图已经有环那么肯定无解,若无环我们一定能通过拓扑序构造一个图使图无环。证明:先跑一个拓扑排序,对于一个无向的边,我们只要把边:从拓扑序小的指向拓扑序大的 就能保正不产生环(拓扑序的定义!)#include<bits/stdc++.h>using namespace std;#define lsn (u << 1)
2021-07-21 20:34:48
121
原创 Codeforces Round #661 (Div. 3) E2. Weights Division (hard version)
传送门题意:给你一颗带权树,现在定义 s = 根到所有叶子的路径和。现有S,你现在可以将每条边的权值 / 2,对不同的边进行除2操作有不同的费用(1或者2),现在求最小的花费,使s <= S。思路:第一印象是二分答案,但枚举答案并没有什么用。我们这样思考,最后的花费无非就是进行x次费用1的操作,y次费用2的操作,那么,我们可以事先计算好进行i次费用1操作所能减少的最大值,j次费用2操作所能减少的最大值,然后枚举其中一个的个数 另外一个可以用二分找到能满足要求的最小的次数。发现这种对结果只有两种
2021-07-20 10:08:14
117
原创 P2184 贪婪大陆
传送门题意:有两个操作 1:在l,r上放上一条线段 操作2:l,r被多少条线段覆盖。思路:通过思考可以发现 前端在r之前的线段都可能覆盖[l,r],那么只有其中后端在l之前的线段不会覆盖,覆盖的就是两者之差。线段树/数状数组维护#include<bits/stdc++.h>using namespace std;#define lsn (u << 1)#define rsn (u << 1 | 1)#define mid (l + r >>
2021-07-16 16:59:48
153
原创 树的直径
定义:图中所有最短路径的最大值即为「直径」。做法:两次dfs O(n)重要性质:树上任意一点的所能达到的最长距离的另一端点,必定是直径两端点之一。故求最长距离直接取两个直径端点到它的距离的max就行了。HDU 2196#include<bits/stdc++.h>using namespace std;#define lsn (u << 1)#define rsn (u << 1 | 1)#define mid (l + r >> 1)t
2021-07-15 10:36:14
136
原创 Educational Codeforces Round 110 (Rated for Div. 2) D. Playoff Tournament
传送门题意:给你含有2^k-1课节点的满二叉树,对于叶子节点权值:’?‘ = 2, ‘1’ = 1, ‘0’ = 1; 对于非叶子节点 ’?‘ = lsn + rsn, ‘1’ = rsn, ‘0’ = lsn(lsn, rsn分别对应左右节点的权值)。有q次查询,每次把某个节点的字符修改为 ?1 0 中的一个,求修改后根节点的点权。思路:因为只修改一个点,那么这个点影响的只有它的父亲节点,所以我们把每个节点的点权全部记录下来,然后对于修改后的节点向上递归,一直到根。 边递归边修改。k 最大为18 所以
2021-07-14 15:48:54
243
原创 Codeforces Round #717 (Div. 2) D. Cut
传送门题意:数组有n个数,有q次询问,每次询问给你一个区间l,r,问[l, r]最少的划分次数是多少。划分的规则为:每个划分后的区间每个数都互质。思路:对于每次询问,要想划分次数最少显然我们得贪心的令子区间的长度最长。求子区间的最长长度思路很简单,从i开始一直往后遍历一直到gcd不为1为止(互质)。现在我们就可以得到以i开头,最长的划分区间了。对于每次询问我们就可以直接算次数了。但我们能直接暴力的算次数吗?显然不行,当每个数都为1时可以把我们卡上天。那怎么办? 倍增现在我们思路都已经很清楚了,那么怎么
2021-07-14 11:23:25
150
原创 Codeforces Round #705 (Div. 2) D. GCD of an Array
传送门题意:给你一个数组含有n个数,同时进行q次操作,每次操作让x位置上的数乘上v,每次操作后输出给个数组的gcd。最大公约数:于是我们有这样的想法,对于每个素数,我们维护n个数中的最小值。显然区间最小值可以用线段树维护,但那样我们不是要开s课线段树?内存显然不够用。1.考虑离线处理 每次算乘上这个数后对结果的贡献(指数是相加的),同样对于刚开始的n个数,我们可以看作最开始每个数都是1,然后依次乘上ai。每次算贡献 我们可以一次把所有p的贡献算完,算完后再清空线段树就可以重复利用了。#incl
2021-07-13 19:03:47
186
原创 Codeforces Round #731 (Div. 3) F. Array Stabilization (GCD version)
传送门题意:给你含有n个元素的数组,每一次操作把ai变为gcd(ai, ai+1)。问最少需要多少次操作可以令数组的所有元素相等。思路:首先我们可以反应过来最后相等的元素就是数组所有元素的gcd,当我们进行k次操作时,ai = gcd(ai, ai+1, ai+2,…,ai+k)。同时我们发现答案是线性的,可以二分,问题是怎么快速得到k操作后每个元素的值。线段树或者ST表就行了,关于ST表有一篇不错的文章。传送门哦对了这种成环的数组可以化环为链,长度为2*n,比较好维护一些。线段树版本#inclu
2021-07-12 20:35:25
191
原创 P4551 最长异或路径
传送门异或的性质:满足交换律满足结合律0异或任何数等于那个数本身写一个关于这种树上异或路径的小总结:设dis(i, j)为i到j的异或路径,k为该树的root,那么有 dis(i,j) = dis(k, i) ^ dis(k, j);证明如图思路: 求出任意点到根节点的异或路径,然后把这些值存到trie中。根据贪心的性质,我要尽可能的让高位为1,剩下的位能为1就尽量为1。trie能很好的进行这些操作。#include<bits/stdc++.h>using namesp
2021-07-07 11:20:07
142
原创 Codeforces Round #729 (Div. 2) C. Strange Function
传送门题意:函数f(n) = 第一个不为n的因子的数,求f(i)的和。思路:n这么大肯定考虑算贡献。关键是求f(i) = x, i 的个数显然,如果f(i) = x,那么肯定有因子1,2,3…,(i-1),那么lcm(1到i-1)就为含有这些因子的最小值,n / lcm(1到i-1)就为1到n中含有这些因子的数的个数,f(i) = x要求x不为i的因子,含有1,2,…i这些因子的最小的数为lcm(1到i),含有n / lcm(1到i)个。相减即为要求的个数。#include<bits/st
2021-07-06 21:00:19
360
原创 POJ - 2763 Housewife Wind
传送门第一次遇到这么有意思的题目。首先介绍一下dfs序。dfs顾名思义 是用dfs遍历一棵树时,各节点出现的顺序。这样可以把一个无序的问题转换为有序的。dfs最大的特点是一个点的子树一定是一段连续的区间。那么这一题首先要把边权转换为点权,为什么呢?显然dfs序是针对点的,这样转换好处理。其次,怎样转换?假设有一条边的两个顶点为v, u且v的深度大于u的深度。那么我们可以把边权看作是较深点的点权也就是v,这样是可以的,因为每个点只有一个父亲。之后我们修改值只需要在in[v]处加上val,在out
2021-07-05 16:03:28
195
原创 AISing Programming Contest 2021(AtCoder Beginner Contest 202)D - aab aba baa
传送门这是个什么神仙题题意:一个字符串由A个‘a’,B个‘b’,要求字典序第K大的数。思路:我们可以根据K的值来确定第i位是放‘a’还是放‘b’。设C(i,j)为放i个‘a’,j个‘b’的方案数。当K <= C(i-1, j)时,我们可以确定这里是放‘a’的,因为所有以a开头的都小于b开头的。当K > C(i-1, j)时,这里放b。当我们确定第i位放a时我们要找的就是C(i-1,j)中的第K大放b时我们要找的就是C(i,j-1)中的第k - C(i-1,j)大。因为数据小C(i
2021-06-09 20:36:25
232
1
原创 P4342 [IOI1998]Polygon
传送门思路:区间dp,套路很常见,需要注意一点的是*的情况,因为顶点的值有正有负所以可能出现两个负数相乘的值大于两正数相乘的值,故我们还得求一个去区间最小值。#include<bits/stdc++.h>using namespace std;typedef long long LL;typedef pair<int, int> P;const int maxn = 100 + 10;const LL INF = 1e17;const int MAX_LOG_N
2021-06-03 13:08:15
182
原创 挑战程序设计竞赛 折半枚举
折半枚举的思想就是如果直接暴力复杂度太大,我们可以先枚举一半,再通过这些值再枚举另外一半算出结果。传送门poj 2785 4 Values whose Sum is 0题意:有四个数组,每个数组的大小都为n,要求从各个数组中各找一个数使a + b + c + d = 0;思路:a + b + c + d = 0 -> a + b = -(c + d), 我们可以枚举a数组和b数组所有和的结果,然后再枚举c + d的同时用二分找到符合结果的个数。#include<iostream>
2021-05-31 19:29:35
130
原创 Codeforces Round #716 (Div. 2) C. Product 1 Modulo N
传送门题意:一个序列1 到 n-1 从中找到最长的子序列使他们的乘积 mod n == 1;思路:我想的是找到最大的子序列乘积为 nk + 1,就是这个+1,我没有往深入想,显然 nk + 1 与 n 互质,所以我们要选择的元素必须与n互质。我们从头开始乘,如果最后结果 mod n == 1,结果就是这个序列,若不是,我们在乘的过程中跳过这个数,结果相当于是除了它本身,结果为1。#include<bits/stdc++.h>using namespace std; typede
2021-05-28 18:33:12
119
原创 HDU - 4578 Transformation
传送门题意:操作1:l r 加上 c操作2 : l r 乘上c操作3:l r 全部变成c操作4:求l r 每个元素的p次幂的和思路:显然是线段树,这题主要卡在了在pushdown的时候不知道是先乘,还是先除。看了dalao的博客后是这样解决的,假设我们先 * muti 再 + add :a * muti + add 没有任何问题,但我们先 + add 再 * muti :a * muti + add * muti;于是我们可以看出来了,每次乘不仅lazy_muti 要乘上muti且lazy_ad
2021-05-28 17:15:55
142
原创 E. Arranging The Sheep
传送门题意:x轴上有n个点,分布在不同的位置,要求把它们排在一起所花费的最小代价。思路:我只知道得往中间排,然后猜了一个中点不变因为不知道该向上取整还是向下,就枚举了一下hhhh。看题解是啥中位数定理,大概就是说 在数轴上有连续的n家居民,在数轴上建立一家商店,使得商店到各个居民的距离之和最小。这个点就是中点。在这题中得向上取整。#include<bits/stdc++.h>using namespace std; typedef long long LL;typedef pai
2021-05-25 19:52:29
131
原创 POJ 3061 Subsequence
传送门双指针#include<iostream>#include<algorithm>#include<utility>using namespace std;typedef long long LL;typedef pair<double, double> P;const int maxn = 1e5 + 100;const LL INF = 1e18;const double eps = 1e-6;const LL mod = 1
2021-05-22 23:51:55
80
原创 wustacm2021周赛3 打怪兽
传送门水一手双指针#include<bits/stdc++.h>using namespace std;typedef long long LL;typedef pair<double, double> P;const int maxn = 2e5 + 100;const LL INF = 1e18;const double eps = 1e-6;const LL mod = 1e9 + 7;int arr[maxn];void solve() {
2021-05-22 23:48:32
157
原创 Mynavi Programming Contest 2021(AtCoder Beginner Contest 201)E - Xor Distances
传送门题意:给你一棵树,问所有路径(不重复)上边权的异或和。思路:我很想说它是一题套路题,当我确实没有把它转换出来。。。。这里直接给出官方题解上的思路从而转换为我们熟悉的按位算贡献问题。依次枚举每一位,最多是2^60 - 1 枚举到第60位就行(其实这个无所谓,比最大值大就行),因为是选择两个dis(x,i),故只有出现 1 0 的情况才能对结果做出贡献。#include<bits/stdc++.h>using namespace std;typedef long long L
2021-05-18 20:26:04
549
4
原创 Educational Codeforces Round 109 (Rated for Div. 2) C. Robot Collisions
传送门题意:有一些机器人分布在x轴上,各自向左右以1个单位每秒的速度行动。仅当相遇在整数位置时两个机器人发生爆炸。撞到墙了即反向。思路:首先观察发现,x为奇数的只可能与x为奇数的相撞,同理偶数。故奇偶得分开求。从左往右,当第一个机器人向右运动时,没有人与它相撞。当第二个机器人向左运动时,当第一个机器人向右运动时两者相撞。那么当第三个机器人向左运动时,什么情况会发生相撞呢?即:第一个向右运动的机器人会和他相撞。于是我们可以看出来,其实这是一个栈,存的是第一个向右运动的机器人。当当前机器人向左运动.
2021-05-18 00:02:26
241
2
原创 Educational Codeforces Round 109 (Rated for Div. 2) 1525D - Armchairs
传送门题意:给n个数字,每个数字为0或1,为1的必须向为0的转移,花费为两个数字的下标差。问所有1转移所需的最小花费。思路:看代码。具体怎么证明按递增的顺序匹配看官方题解吧,写的很详细了。#include<bits/stdc++.h>using namespace std;typedef long long LL;typedef pair<int, int> P;const int maxn = 5000 + 10;const int INF = 0x3f3f
2021-05-17 20:30:37
220
1
原创 牛客小白月赛25-J异或和之和
传送门题意:给出n个数,求所有3元组的异或的和。思路:考虑一个单个bit上三个数异或后的结果,只有当:三个数全为1:1 1 1 和一个为1,两个为0 : 1 0 0 ;才会在此位上给结果作贡献。最大的数为1^18,所以我们直接存上63个位置上1的个数和0的个数,然后用组合数直接求这位上的贡献就可以了。#include<bits/stdc++.h>using namespace std;typedef long long LL;typedef pair<int, int&
2021-05-17 18:59:05
192
原创 Codeforces Global Round 14 C. Phoenix and Towers
传送门题意:有n个方块,每个方块有各自的高度且不大于x。把n个方块堆成m座塔,且要求任意两座塔之间的的高度差不能大于x。思路:每次取高度最小的塔,把当前方块堆上去。以下简单证明:假设现有的塔是合法的,我们给最低的塔加上一个不大于x的高度,它于原先倒数第二高的塔的距离必定小于等于x。因为他们俩原先的高度差最极限是一样高,加上一个x还是合法。当不一样高时,加上之后的高度差小于x,肯定合法。#include<bits/stdc++.h>using namespace std;typede
2021-05-15 19:16:12
149
原创 KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200)D - Happy Birthday! 2
传送门我们可以看出,B©序列的所有情况一共有2^n - 1种(就是每个数取或者不取),直接枚举肯定是不行。再继续观察题目给出的条件,求和后要对200取模,也就是说取模后的结果有200种情况。我们所有序列的情况一共2^n - 1种,取极限情况,当前200种情况所得的结果都不相同时,第201种情况必定出现重复,因此只要情况总数超过200时必定有解。我们可以取n = 8(2 ^ 8-1 > 201)然后找到两种相同的情况即可。当n < 8 时,我们也可以采用同样的方法枚举。不知道为什么开200的
2021-05-09 10:13:34
742
3
原创 ZONe Energy Programming Contest E - Sneaking (最短路)
传送门前三个移动按照题目描述连边就可以。现在考虑最后一个移动:如果直接连边,边的总数肯定就炸了。我们可以考虑建一个虚顶点,普通顶点的编号为(i - 1) * m + j,对应虚节点的编号为(i - 1) * m + j + n * m。我们可以让普通顶点与虚顶点连一条权值为1的边,虚顶点向顶点连一条权值为0的边,然后虚节点向它的上一个虚节点连一条权值为1的边((i - 2) * m + j)。为什么这么考虑呢?因为题目说的从后往前移动的花费为i + 1,这个1就对应了顶点到虚节点的权值,i就相当于虚节
2021-05-06 14:29:15
151
原创 ZONe Energy Programming Contest C - MAD TEAM (二分 + 状压) (好题)
传送门第一眼就想到了二分但不会写check…我们要保证选出的三个人中,每项能力至少有一个人 >= mid,我卡在了这里不知道怎么枚举…我们可以将每个人每项能力的状态压缩, >= mid 的 就为1,否则为0。现在问题转换为是否能找到3个人,使他们的状态 | 起来为(1 << 5) - 1,这样就满足了 每项能力至少有一个人 >= mid。可直接暴力,复杂度为2 ^ 15。也可以用dp保存中间状态,复杂度为 5*2 ^ 10。暴力版本#include<bits/
2021-05-05 17:16:20
319
1
原创 Codeforces Round #621 (Div. 1 + Div. 2) C. Cow and Message
传送门题目要求子串最大的数目是多少,且要求下标满足等差数列。(英语不好的我第一次写硬是没看出来那几个单词是等差数列的意思)很明显,当我们选择的字串长度为1 or 2时,我们不用考略等差数列的要求。当长度大于2时一定得先构建长度为2的字串且还要增加限制,所以数量一定会变小。#include<bits/stdc++.h>using namespace std; #define de(x) cout << #x << " == " << x <&l
2021-05-03 17:38:52
166
原创 Educational Codeforces Round 108 (Rated for Div. 2) D. Maximum Sum of Products
传送门虽然说并没有系统学过区间DP,但这题的状态转移方程真的不难推,自己在打cf的时候过于在乎rating的变化而忽略了更为重要的东西,以此为戒。令dp[i][j]为反转区间[i,j]所获得的价值。dp[i][j] = dp[i+1][j-1] + a[l]*b[r] + a[r]*b[l] - a[l]*b[l] - a[r]*b[r];可记忆化搜索可递推#include<bits/stdc++.h>using namespace std; #define de(x) cout
2021-04-30 19:47:30
155
1
空空如也
关于流输出重载的问题
2020-12-07
TA创建的收藏夹 TA关注的收藏夹
TA关注的人