摘要:有N张卡片,第i张卡片上的数字为x[i],可以从中选择1张或多张卡片,要求平均数为A,求方案数。 1<=N<=50; 1<=A<=50; 1<=x[i]<=50 分析:由于N最大为50,dfs搜索会超时,考虑dp。记dp[i][j][k]表示前i张卡片中选择了j张,并且和为k,根据每张卡片选与不选进
阅读全文
摘要:给定二维平面上的N个不同的点,坐标分别为(X[i],Y[i]),问存在多少条直线穿过至少K个点? 1<=K<=N<=300;|X[i]|,|Y[i]|<=1E9 分析:最多只有300个点,可以枚举所有点对构成的直线,用斜率和截距表示,为了避免精度问题,两者用分数来表示。注意,平行与x轴和y轴的直线要
阅读全文
摘要:现有大写英文字母A-Z,个数分别为C[i],总共可以组成多少个长度在[1,K]之间的不同串?答案对998244353取模。 1<=K<=1000, 0<=C[i]<=1000 分析:记dp[i][k]表示前i类字母构成长度为k的不同方案数,枚举第i类字母的个数j进行转移。 #include <bit
阅读全文
摘要:有序列A[N]和B[N],选出一组大小为K的下标,让A[i]的最大值乘以(B[i]之和)的结果最小,求最小值。 1<=T<=2E5, 1<=K<=N<=2E5, 1<=A[i],B[i]<=1E6 分析:因为A[i]跟B[i]要同步选,因此对下标排序,然后枚举每个A[i]作为最大值,从B[i]中选出
阅读全文
摘要:有N个顶点M条边的简单有向图,求包含1号点的最小环的顶点数,如果不存在,输出-1。 2<=N<=2E5, 1<=M<=2E5 分析:bfs求最小环。 #include <bits/stdc++.h> using i64 = long long; void solve() { int N, M; st
阅读全文
摘要:有N个玩具,大小分别为A[i];另外有N-1个盒子,大小分别为B[i]。现要再买一个盒子,把所有玩具装到盒子里,要求每个玩具都装一个盒子,并且玩具大小不超过盒子大小。问买的盒子至少为多大?如果无法满足,输出-1。 2<=N<=2E5, 1<=A[i],B[i]<=1E9 分析:将玩具按从大到小排序再
阅读全文
摘要:由1~N的块构成的环,最初左手在1号、右手在2号,接下来有Q组操作{H, T},H可以是L或者R,分别表示左手和右手,T是目标位置,移动时要求左右手不能在同一个块上。 3<=N<=100, 1<=Q<=100 分析:模拟,关键在于如何判断是顺时针移动还是逆时针移动。 #include <bits/s
阅读全文
摘要:给定整数N,已知N可以写成ppq的形式,其中p和q为不同质数,求p和q。 1<=N<=9E18 分析:p与q的最小值不超过3E6,可以枚举。 #include <bits/stdc++.h> using i64 = long long; std::vector<int> minp, prime; v
阅读全文
摘要:埃氏筛法,时间复杂度O(nloglogn)。 std::vector<int> minp, prime; void sieve(int n) { minp.assign(n + 1, 0); prime.clear(); for (int i = 2; i <= n; i++) { if (minp
阅读全文
摘要:可以考虑将单个int类型映射成3个uint64,再执行加减操作,从而实现将多个int的集合最终映射成3个uint64,通过比较这3个uint64是否相等来快速判断集合是否相同。 由于加法满足交换律,与顺序无法,因此上述做法天然支持多重集合。对于单重集合,可以考虑再加个set维护当前插入了哪些元素,已
阅读全文
摘要:在Treap的基础上增加了前缀和接口,使用时TYPE一般指定为i64类型,新增接口如下: 最小的k个元素之和:ksum(相同元素有几个就算几个) 最大的k个元素之和:kSum(相同元素有几个就算几个) template <typename TYPE> struct SumTreap { struct
阅读全文
摘要:基于treap实现的平衡树,支持以下操作和特点: 定义时不需要指定大小上限,会自动分配空间。 已删除的节点空间会回收,并重复利用。 默认为可重集合,如果希望相同元素只存1个,可以在定义时将multi参数设为0,或者在定义后通过setmulti接口设置。 支持insert/erase操作,同时可以通过
阅读全文
摘要:版本1:求n的所有质因子,时间复杂度O(sqrt(n))。 // 例如:12=2*2*3,那么 // factor(12, 1) => {2,3} // factor(12, 0) => {2,2,3} std::vector<int> factor(int n, int removeDup) {
阅读全文
摘要:版本1:路径压缩。 struct DSU { std::vector<int> fa; void init(int n) { fa.resize(n + 1); std::iota(fa.begin(), fa.end(), 0); } int leader(int x) { while (x !=
阅读全文
摘要:使用前需要初始化,执行一次comb.init(n),n为C(n,m)中最大的n。初始化时间复杂度为O(n),后续每次求comb(n,m)时间复杂度为O(1)。 std::vector<mint> fac, ifac; struct Comb { void init(int n) { fac.assi
阅读全文
摘要:输入为int64类型,底层用int64表示,每次运算后自动取模。 template<int MOD> struct MInt { i64 x; int norm(i64 u) const {u%=MOD; if(u<0) u+=MOD; return u;} MInt(i64 v=0):x(norm
阅读全文
摘要:给定整数N,每次可以选择支付X元将其除以A并向下取整,或者支付Y元掷筛子,假设点数为i,则将其除以i并向下取整,筛子每次都是等概率出现1-6。问将N变成0需要的最小花费的期望。 1<=N<=1E18; 2<=A<=6; 1<=X,Y<=1E9 分析:当前的期望是所有后续情况期望的概率加权。如果选择方
阅读全文
摘要:给定数组A[N],有Q个询问,每个询问给出l[i]和r[i],问区间[l[i],r[i]]内有多少个不同的数? 1<=N,Q<=5E5; 1<=A[i]<=N; 1<=l[i]<=r[i]<=N 分析:对询问按右端点从小到大排序,然后从左到右依次处理每个A[i],将下标i的位置置为1,如果前面出现过
阅读全文
摘要:有数组A[N],初始时元素都为0,另外还有初始为空的集合S。依次处理以下Q组查询:给出整数x[i],如果S包含x[i],则从S中移除x[i],否则将x[i]加入S,记此时S的大小为|S|,把|S|加到集合中的每个元素i对应的A[i]中。求最终A[i]是多少。 1<=N,Q<=2E5; 1<=x[i]
阅读全文
摘要:给定数组A[N],对所有1<=i<j<=N,计算max(A[j]-A[i],0)之和。 2<=N<=4E5; 0<=A[i]<=1E8 分析:从左到后依次处理,用平衡树维护左侧A[i],对于A[j],只需要统计值小于A[j]的那些A[i]即可,可以合并求和过程转化为前缀和。 #include <bi
阅读全文
摘要:给定数组A[N],对所有1<=i<j<=N,计算max(A[i],A[j])/min(A[i],A[j])之和,除法为向下取整。 2<=N<=2E5; 1<=A[i]<=1E6 分析:排序不影响结果,先对A[N]排序和计数,然后枚举每个数作为除数时产生的商,注意数可以重复,因此重复的数要单独统计,以
阅读全文
摘要:生产某种产品有N道工序,对于工序i,有S[i]和T[i]两类机器可供选择,机器S[i]单价为P[i],每台每天能处理A[i]件;机器T[i]单价为Q[i],每台每天能处理B[i]件。在不超预算X的前提下,每天最多能生产多少件产品? 1<=N<=100; 1<=A[i],B[i]<=100; 1<=P
阅读全文
摘要:有红蓝两种糖果,红色糖果每颗重wr克,甜度为hr;蓝色糖果每颗重wb克,甜度为hb;有容量为C克的盒子,求能装下的最大甜度。 1<=C,hr,hb,wr,wb<=1E9 分析:记S=lcm(wr,wb),那么对于S克容量,可以装S/wr颗蓝色糖果,也可以装S/wb颗红色糖果,甜度分别为S*hb/wr
阅读全文
摘要:有N个岛和M座双向桥,编号为i的桥连接岛U[i]和V[i],过桥耗时T[i],桥连接两不同的岛屿,两个岛之间可能会有多座桥。 有Q组询问,每次询问给出K座桥,问从1号岛到N号岛的最少耗时,要求给出的K座桥分别至少经过1次。 2<=N<=400; N-1<=M<=2E5; 1<=U[i]<V[i]<=
阅读全文
摘要:有N只怪兽,第i只怪兽的体力为A[i],需要按编号从小到大的顺序依次处理,对于每只怪兽可以选择打或不打,如果不打,经验值不变;如果打,将获得等同于怪兽体力的经验值。另外,对于第偶数次打的怪兽,经验值翻倍。求能获得的最大经验值。 1<=N<=2E5; 1<=A[i]<=1E9 分析:获得的经验跟奇偶性
阅读全文
摘要:有长度为N的数组A[i]和整数K,需要将A划分成连续子数组,要求每个子数组之和不能为K。问有多少种方案,答案对998244353取模。 分析:如果不考虑和不为K的限制,就是个O(n^2)的dp,通过前缀和可以优化成O(n)。现要求子数组和不为K,可以用容斥思想先全部加上,然后减去不符合条件的部分。对
阅读全文
摘要:有H行W列的格子,初始时每个格子中都是墙,接下来有Q组询问,格式为:R[i] C[i],表示在坐标(R[i],C[i])的地方放置炸弹,如果该位置是墙,则墙被炸掉,如果是空地,则上下左右最近的一格墙被炸掉。问最终还剩多少墙? 1<=H,W; H*W<=4E5; 1<=Q<=2E5; 1<=R[i]<
阅读全文
摘要:给定长度为N的数组A[i],记f(l,r)表示区间[l,r]内不同A[i]的个数,求所有子区间f(i,j)之和。 1<=N<=2E5, 1<=A[i]<=N 分析:贡献法,为了方便统计,区间中重复的数字以最左边出现的数为准,保证不重不漏。对于A[i],假设其上一次出现的位置为p,那么包含该数字的左端
阅读全文
摘要:有N个顶点的无向图,最初没有边,接下来有Q组询问,格式如下: 1 u v:在顶点u和v之间加一条边; 2 x k: 问与顶点v连通的分量中,顶点编号第k大的是谁?如果不存在,输出-1. 1<=N,Q<=2E5,1<=u<v<=N, 1<=x<=N, 1<=k<=10 分析:由于k比较小,直接用vec
阅读全文
摘要:N幢楼排成一行,第i号楼的高度为H[i]。对于每幢楼,右边有多少幢楼满足两楼之间的楼高都不超过右侧楼高? 1<=N<=2E5, 1<=H[i]<=N, H[i]!=Hj 分析:单调栈求出各幢楼左边最近的比它高的楼,对于j号楼,假设它左边最近的比它高的楼号为i,那么j对区间[i,j-1]中每个下标都有
阅读全文
摘要:有N个候选人和总共K张选票,目前第i个候选人的票数为A[i]。在全部选票统计完成后,如果得票数多于自己的人数小于M,则当选,可以多个人同时当选。对于每个人,输出当选需要再获得的最少票数。 1<=M<=N<=2E5, 1<=K<=1E12, 0<=A[i]<=1E12, sum(A[i])<=K 分析
阅读全文