2021暑假集训
哈希表扁豆
此人不懒,但什么都没写
展开
-
J - Joining Capitals(最小斯坦纳树变形)
Problem给定平面n个点的坐标,其中前k个为选中的点,求包含这k个点的最小代价且这k个点必须作为树上的叶子结点。一开始想乱暴,查了查是个斯坦纳树,之前听都没听说过。斯坦纳树斯坦纳树问题是组合优化问题,最小斯坦纳树允许在给定点外增加额外的点,使生成的最短网络开销最小。Pollak-Gilbert猜想:平面上任意n点集,斯坦纳最小树长与最小生成树之长的比值的最小值是sqrt(3)/2。Solution通过状压DP解决最小斯坦纳树问题,dp[i][S]表示已i为根包含集合S中所有点的最原创 2021-08-25 20:26:00 · 183 阅读 · 0 评论 -
SDKD 2021 C1 8th Round
A - Parity签到,根据奇数偶数的预算性质。#include <iostream>#include <cstdio>using namespace std;int a,b,k,ans;int main(){ cin>>b>>k; for(int i=k-1;i>=0;i--) { scanf("%d",&a); if(b%2&&a%2||a%2&原创 2021-08-23 13:59:37 · 133 阅读 · 0 评论 -
SDKD 2021 B 7th Round
A - Ticket签到题#include <iostream>#include <cstdio>using namespace std;const int MAXN = 1e5+7;double a[MAXN];int main(){ int n; double sum=0; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%lf",&a[i]);原创 2021-08-22 11:34:17 · 158 阅读 · 0 评论 -
H - Clock(思维+小模拟)
Problem有个表,给定初始时刻和一些其他时刻,求秒针总共最少转多少度使得经过所有时刻。Solution场上唯唯诺诺,场下重拳出击。。。想了想实际最优情况应该是一直往某个方向转,或者转到某个位置,然后沿反方向走完剩下所有的。处理时把时间化为秒,去重,特判初始位置在两头时和一遍走完的两种情况,所有的取最优,没啥细节。Code#include<iostream>#include<cstdio>#include<algorithm>using name原创 2021-08-22 11:09:33 · 117 阅读 · 0 评论 -
K - Tetris(观察找规律)
Problem用给定的一种俄罗斯方块把矩形铺满。solution样例给的4*4的矩形就是最小符合情况的单元,行或者列需要同时是4的倍数的时候才可以。场上的观察能力真的差,也被数据范围骗了,以为是给暴搜。Code#include <iostream>#include <cstdio>using namespace std;int n,m;string s[5];int main(){ s[0]="1113"; s[1]="2133"; s[2]="原创 2021-08-22 06:31:23 · 226 阅读 · 0 评论 -
D - Tree(树剖+线段树维护区间开根号)
Problem给定一颗大小为n的树和q此操作,op0:将一条树链上所有点的权值开根号;op1:求一条树链上所有点的权值和。Solution显然要用树剖将树映射到区间上,看到区间和时想用线段树维护,场上感觉线段树好像没法通过打标记维护区间开根号。点权是小于等于1e9的,对于一个点来说最多开六次点权就会变为1,如果某个区间的区间和为r-l+1,就不需要对这个区间再进行开根号操作。因此可以维护一个没有pushdown的线段树,暴力修改到底开根号,效率上最差(全部单点开根号开到1)应该是一般线段树的六分之原创 2021-08-22 06:04:48 · 373 阅读 · 0 评论 -
SDKD 2021 C3 7th Round
A - Yellow Cards签到题#include <iostream>#include <cstdio>#include <algorithm>using namespace std;int n,a1,a2,k1,k2,mx;int main(){ cin>>a1>>a2>>k1>>k2>>n; int tot=a1*(k1-1)+a2*(k2-1); cout&原创 2021-08-21 21:05:59 · 100 阅读 · 0 评论 -
C - Convex Contour(轮廓线)
Problem求轮廓线,图形由三角,圆,正方形拼成,三角为等边三角形。Solution大体框架还是找到最左边和最右边的方或圆(可以将轮廓线撑起来),然后算出两边三角包括三角与其他图形相连部分的轮廓线长度,然后算中间部分的轮廓线长度。注意三角和圆轮廓线是与圆相切的。Code#include <iostream>#include <cstdio>#include <cmath>using namespace std;const double pai原创 2021-08-21 20:38:22 · 172 阅读 · 0 评论 -
SDKD 2021 C1 7th Round
A - Creating a Character签到题#include <iostream>#include <cstdio>using namespace std;int t,a,b,c;int main(){ cin>>t; while(t--) { int ans=0; scanf("%d%d%d",&a,&b,&c); int cha=a+c-b;原创 2021-08-20 15:38:10 · 104 阅读 · 0 评论 -
CodeForces - 1209C Paint the Digits
Problem给定序列,要求对序列中的每个数字用1或2染色,然后将染为1的数字按原序列的相对顺序放在新序列前面,将染为2的数字按原序列的相对顺序放在新序列后面,求一染色方案使新序列单调不降。Solution考虑到数字是从0~9,可以枚举新序列染色为1和染色为2交界处的数字大小,小于所枚举数字的染为1,大于所枚举数字的染为2,所枚举数字尽可能染为2,看能否使得两部分分别单调不降。时间复杂度O(t*n)。Code#include <iostream>#include <cstdio原创 2021-08-17 19:41:03 · 96 阅读 · 0 评论 -
D - Hangar Hurdles(kruskal重构树+树上倍增)
Problem给出n*n由.和#组成的网格,q组询问,每组询问给出起点和终点,求每次将箱子从起点推向终点的最大箱子边长(障碍不能在箱子所占范围内)。n<=1000,q<=300000。4s,512M。Solution一开始想用floyd预处理,然后O(1)查询,但点的数量级为1e6,会T。由此题可推出的小结论:当最短路问题的距离定义为路径瓶颈时,答案等价于最值生成树上路径的最值。预处理求出以每个点为中心的箱子最大边长,一次bfs或者二维前缀和+二分,bfs时从障碍往外bfs。正原创 2021-08-17 19:16:19 · 167 阅读 · 0 评论 -
SDKD 2021 C1 6th Round
A - There Are Two Types Of Burgers签到题#include <iostream>#include <cstdio>#include <cmath>using namespace std;int t,bun,beef,chi,h,c;int main(){ cin>>t; while(t--) { int ans=0,tmp; scanf("%d%d%d%原创 2021-08-16 15:44:56 · 142 阅读 · 0 评论 -
K - TV Show Game
Problem一群人猜气球,每个人猜三个,每个气球有红蓝两种颜色,求是否存在让每个人至少猜对两个气球的气球颜色方案。Solution2-sat模板题,场上没往这方面想。2-sat问题解法+证明+模板2-sat解决的什么问题?满足必须满足的约束条件:选了一些必须选另一些。本题中对于一个人来说猜错了某个气球则意味着其它两个气球必须猜对,根据此约束条件建图即可:2i表示第i个气球为红色,2i+1为蓝色,枚举每个人猜错的那个气球建图。Code#include <iostream>#i原创 2021-08-15 17:49:49 · 285 阅读 · 0 评论 -
I - Ideal Pyramid(平面几何)
Problem求金字塔的塔尖坐标,使给定的所有点都在金字塔内部,金字塔斜边45度角。Solution高恰为边长的一半,给定的每个位置可转换成平面上的正方形,求覆盖所有正方形的最小正方形。Code#include <iostream>#include <cstdio>#include <cmath>using namespace std;int n,x,h,y,xl=1e8,yl=1e8,xr=-1e8,yr=-1e8;int main(){原创 2021-08-15 10:39:30 · 178 阅读 · 0 评论 -
E - Equidistant(bfs)
Problem给定一棵树和树上一些点,求任意一个树上到所有给定点距离相等的点。Solution直接对所有选中的点往外bfs,但是需要一些超越常数的优化,要不然又TLE又MLE。记录所有选出的点到每个点的最短距离,记录选中的点在最短距离下到达其他点的次数,只在第一次访问的时候(最短距离)push(这样保证了每个点只进队一次),相等的时候更新最短距离下到达的该点的所选中点的数量。注意检查极限情况是否能算对。Code(写的很乱)#include <iostream>#include原创 2021-08-14 20:33:42 · 167 阅读 · 0 评论 -
【2019 NWERC - E】Expeditious Cubing 【★】
Problem【★】最终成绩为五个成绩去掉最好和最差两个成绩剩下三个成绩的平均数,现在Claire已经有了四个成绩,给定他听得比赛所需的最小最终成绩,求他第五次成绩最差是多少时能赢得比赛,或者无论如何都能赢得比赛,或不可能赢得比赛。Solution【★★】最终成绩一定在四个成绩最大三个的平均数和最小三个的平均数之间,可用这个边界判断后两种情况,然后用目标成绩和四个里面中间的两个成绩反推第五次最差成绩。会产生精度问题,需要按位当整数读入,放大100倍计算。Code【★】#include <io原创 2021-08-14 18:48:28 · 139 阅读 · 0 评论 -
【2019 NWERC - I】Inverted Deck 【★】
Problem【★】给定一个序列,问能否通过翻转一个子序列使得整个序列为不降的。Solution【★】求单调下降的子序列数是否小于等于1,再验证翻转之后整个序列是否单调不降。Code【★★】#include <iostream>#include <cstdio>using namespace std;int n,a[1000005],pos1,pos2;bool has,ac;int main(){ cin>>n; for(int i原创 2021-08-14 18:35:27 · 135 阅读 · 0 评论 -
H - High Load Database(二分前缀和)
Problem给定序列和q次询问,每次询问给定x,求最少能将序列分成多少段使得每段的和不超过x。n<=2e5,q<=1e5。Solution倍增查找前缀和(不想写二分)预处理出前缀和,对于每组询问在前缀和上倍增的查找下一次分割的位置,一些博客上说时间复杂度是个什么调和级数,效率应该在n和logn之间。可记忆化。场上想到过,脑子一抽以为这样做比暴力还差。。。转而去想常数优化。Code#include <iostream>#include <cstdio>原创 2021-08-14 18:27:10 · 136 阅读 · 0 评论 -
J - Just the Last Digit
Problem给定两个点间的路径数的各位,还原整张图,矩阵表示。只可能编号小的点连向编号大的点。Solutioni到j是否有直接相连取决于所有的k to j(i<k<j且i与k直接相连)的路径数的和是否小于i to j的路径数从大到小枚举i,从小到大枚举j,同时维护与i直接相连的点即可。Code#include <iostream>#include <cstdio>using namespace std;const int maxn=520,mod=10;原创 2021-08-14 17:07:59 · 131 阅读 · 0 评论 -
M - Managing Difficulties
Problem给定数列,求有多少个aj-ai=ak-aj,i<j<k。Solution枚举j和i,倍增差k,如果有,倍增查数量。时间复杂度n^2lognCode#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;int t,n,a[2005],m,cnt[2005],all[2005][2005原创 2021-08-14 16:59:26 · 142 阅读 · 0 评论 -
A - Circuits(线段树维护区间最大值)
Problem求两条平行线穿过的最大矩形。Solution贪心走不通之后场上想到了枚举,考虑到了定一条之后枚举剩下的,然后剪纸。实际上从剩下的里面找最大就是个区间查询最值问题,线段树可维护。不过还有一些细节要处理:首先区间很长,要对矩形进行离散化;每次确定一条的时候不可能把穿过的所有矩形的对应区间进行修改(这样做可能比暴力还差),实际上这样产生的来回修改毫无意义,顺着这条优化思路,能不能想个办法保证每个矩形只对线段树做两次修改操作(离散化产生两个点)?选择一个矩形下边界的时候将其在区间删掉,在选择原创 2021-08-14 00:53:44 · 328 阅读 · 0 评论 -
SDKD 2021 C3 5th Round
A - Deadline签到题,凑双勾函数,注意sqrt(d)和sqrt(d)+1都要算。#include<cstdio>#include<iostream>#include<cstring>#include<cmath>using namespace std;int t,d,n,minn;int main(){ cin>>t; while(t--) { scanf("%d%d",&am原创 2021-08-13 20:51:57 · 135 阅读 · 0 评论 -
HDU - 5009 Paint Pearls(链表优化DP)
Problem给一段染色的代价是这一段不同颜色数的平方,求染完序列的最小代价。Solution动态转移方程显而易见,但是裸的DP会T。通过观察可以发现,当前枚举的断点如果可能成为答案断点的左边一定是右边这一区间没出现过的数。因此我们可以用链表维护,用每个数最新出现的位置更新链表,同时最终答案一点小于等于n,每次枚举只需枚举sqrt(i)次即可。场上想不出优化时可以直接打一下转移的表观察看看。Code#include <iostream>#include <map>#i原创 2021-08-12 17:06:10 · 120 阅读 · 0 评论 -
F - Icebergs(求简单多边形面积模板)
求多个简单多边形的面积和。以原点为基准点,求一圈向量的叉积,注意绝对值。#include<bits/stdc++.h>using namespace std;int n,t;long long x[1005],y[1005];double ans=0,sum;int main(){ cin>>t; while(t--) { sum=0; scanf("%d",&n); for(int .原创 2021-08-01 17:16:38 · 117 阅读 · 0 评论 -
Contest Setting
题意有n个题目,每个题目都有一个难度,从里面选出k个难度不同的题目。赛时思路dp[i][j]表示选出的最后一个题的题目难度为i,已选出题数为j时的方案数,num[i]表示难度为i的题目个数,dp(i+1,j)=(∑k=j−1idp(k,j−1))∗num(i)dp(i+1,j)=\displaystyle \left( \sum_{k=j-1}^i dp(k,j-1) \right)*num(i)dp(i+1,j)=⎝⎛k=j−1∑idp(k,j−1)⎠⎞∗num(i),可通过记录中间量将时间复原创 2021-07-31 19:39:40 · 93 阅读 · 0 评论 -
A - Environment-Friendly Travel(二维最短路)
Question求在路径长度小于等于限制长度前提下起点到终点的最小花费。Solution建图什么的都比较常规,路径长度小于100,求最小花费那就以花费为权跑最短路,剩下的信息当做状态处理好了<node,dist>,注意只保留合法状态(当前距离小于路径长度),跑dijkstra。场上没出是输在对状态的维护上了,dijkstra本质上也是优秀在对同状态对外处理的唯一性上,原来那个写法确实不太能体现这种思想。Code#include <iostream>#includ原创 2021-08-01 16:10:44 · 271 阅读 · 0 评论 -
Number of Simple Paths
题意:给出一个基环树,求图中简单路径数。思路:考虑一个简单环,任意两点的简单路径数为2,其总简单路径数为n*(n-1);因此基环树中的简单路径数就是n*(n-1)-多算的路径数。现在考虑多算的路径是那些:整个图可以看成是一个环,环上的每个点挂着一棵树,由于环上任意两点间的简单路径数为2,不同树上任意两点间简单路径数为2,因此多算的部分只是所有树上的简单路径数,大小为siz(i)的树简单路径数为siz(i)*(siz(i)-1)/2。模拟赛上的思路是分别求,求环上点间的路径数,单棵树上的路径树,不同树上.原创 2021-07-31 11:11:47 · 123 阅读 · 0 评论 -
HDU - 2819 Swap
题意:给出一个01方阵,能否通过交换行或交换列使得方阵主对角线元素全为1,输出方案。思路:裸的二分图匹配。。。模拟赛时想着仅做行的初等变换,但是这个步骤是用来化阶梯形的,不等价于题意要求。。。具体建图:源点向每一行连边,容量为1,每一行向对应位置为1的列连边,容量为1,每一列向汇点连边,容量为1,看匹配数是否为n即可。代码:不写了。...原创 2021-07-31 09:36:06 · 76 阅读 · 0 评论 -
Tunnels(状压DP模板题)
Problem求走过所有隧道所需的最小时间。Solution隧道总数很小,直接状态压缩。dp(i,j)表示已经走完的状态为i,当前在j所需要的最小时间。首先bfs预处理出不同隧道间的距离,将当前已经走过的隧道压缩成二进制数从小到大枚举状态,枚举每个状态的当前所在隧道,枚举当前隧道所能到达的隧道。Code#include <iostream>#include <map>#include <cmath>#include <cstdio>#incl原创 2021-08-11 20:11:27 · 144 阅读 · 0 评论 -
SDKD 2021 C3 4th Round
A - Angry Students签到题#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;int t,n,mx,last;char st[205];int main(){ cin>>t; while(t--) { last=mx=0; cin原创 2021-08-11 12:09:59 · 121 阅读 · 0 评论 -
C - Galaxy(方差)
Problem可移动k个行星,使所有行星的转动惯量和最小,每个行星质量为1,中心为平均位置。Solution只有当剩下的n-k个位置连续时才有可能作为答案,不连续一定不是最优;剩下的k个一定是移动到这n-k个的平均位置时才有可能最优(用二次函数最小值位置可证);维护前缀和和前缀平方和,扫一遍计算答案即可Code#include <iostream>#include <algorithm>#include <cmath>#include <cstdio原创 2021-08-08 20:59:05 · 97 阅读 · 0 评论 -
B3-G-Game of Gnomes(枚举)
Problemn个士兵分m组,每回合造成当前剩余人数点伤害,没回合选人数最多的组杀k个人,问最多能造成多少伤害。Solution枚举杀多少次k个人,剩下的人平分在m组总伤害最大。Code#include <iostream>#include <cstdio>using namespace std;long long n,m,k,ct,ans,mx;long long solve(){ ans = 0; long long x=(n-ct)/k;原创 2021-08-08 17:38:21 · 76 阅读 · 0 评论 -
B3-F-Flow Finder(毒瘤dfs)
Problem给出经过每个点的流量,0代表不确定,将整张图的各个点的流量输出,如果方案不唯一或者有的点最终流量<=0或者出现矛盾,输出impossible。Solution先确定叶子结点的流量,再向上确定其它结点的流量。记录每个点所能确定的其下叶子结点的总权值,如果其确定的叶子结点只有一个或确定的叶子结点数等于其能确定的总权值,就更新这部分叶子结点。注意,一个叶子结点只由它最近的权值不为0的祖宗确定。Code#include <iostream>#include <cs原创 2021-08-08 15:42:45 · 76 阅读 · 0 评论 -
【2019 NWERC - J 】Jackdaws And Crows 【★★★★】
Problem【★★★】有一串序列,你要使得最终的序列正负交替,有两个操作1.用c的代价使任意部分元素+1或-1。2.用r代价删除一个数。问你最后用的代价最少是多少。Solution【★★★★】在k*c的代价下一部分元素变的可正可负,可正可负用?表示,假设一个子序列+??+?+,前两个+显然是不合法的,需要删一个,无论删哪一个都不会影响后面序列的合法性(删除数量)。这个性质使得我们可以在按权值从小到大枚举变成可负可正的点的时候可以O(1)计算此时产生的总代价。0的情况比较特殊,因为对于0来说只原创 2021-08-06 16:04:00 · 274 阅读 · 0 评论 -
【2019 NWERC - D 】Disposable Switches【★★★★】
Problem【★★★】边的权值为l/v+c,其中已知l,求那些点不可能成为1 to n最短路上的点。v>0,c>=0,v与c是确定的数。Model Building【★★★★】spfa+单调栈+dfs。Solution【★★★★】dis[i][j]表示经过j条边到达i的只考虑l下的最短路,经过k条边到达n的最短路为dis[n][k]/v+k*c,以c的大小为x轴,1 to n的最短路为y轴建立平面直角坐标系(v只不影响直线与y轴交点的相对位置,因此也不影响直线件交点的相对位置):原创 2021-08-06 10:40:34 · 199 阅读 · 0 评论 -
B2 - F - Find my Family(单调队列)
Problem如果一组数据左边的一个比自己高,右边的一个比这俩都高,则这组数据合法,问有多少组合法数据。Solution维护单调上升序列,每次加入元素前的删除元素记录所删除的最后一个值,每次删之前拿新元素和这个值比较,如果新元素大则这组数据合法。#include <bits/stdc++.h>using namespace std;int k,n,h[300005],pos,que[300005],ac[1005],num,tmp;int main(){ cin>&原创 2021-08-03 16:40:44 · 68 阅读 · 0 评论 -
CF1379C Choosing flowers
Problemm种朵花,第i种买第x朵收益为ai+(x-1)*bi,问买n朵的最大收益。Solution收益最大的方案一定是买a最大的一部分,剩下的全买一种(不一定是b最大的那个,放在平面直角坐标系中易证)。枚举剩下全买的那个bi,替换掉所有的aj<=bi(对a排序,倍增查找),然后求这种情况下的最大收益。总时间复杂度mlogm,细节挺容易写错。Code#include <iostream>#include <cstdio>#include <queue&g原创 2021-08-02 14:59:27 · 112 阅读 · 0 评论 -
K - Birdwatching
Problem给点t,求有多少点使得断开其与t直接相连的边后没有从其到t的路径,求出这些点。Solution首先建反向图,此时变成了“单源”问题,记可能为答案的点组成集合S,以当前点与出发点组成的二元组为状态进行bfs,如果当前点与出发点相同就不增加对它的访问次数,也不再对它往外bfs。如果能够到达一个点多次说明这个点不满足要求。上述做法如果中间出现环会有无限次进队,因此考虑剪枝,一个一般的点如果能被两个不同的出发点到达那么此时从第三个及以上的出发点到达该点所组成的状态已经不会对最终答案产生影响,因原创 2021-08-02 16:10:59 · 191 阅读 · 0 评论 -
B2 - H - Historic Exhibition(二分图匹配+优化建图)
Problemn个花瓶,每个花瓶有一个编号,m个台柱,台柱上下各有两个编号,当花瓶编号与台柱编号相匹配时花瓶才能放在台柱上,每个台柱上最多能放一个花瓶,求能否将所有花瓶放上台柱,输出方案。n<=1e4,m<=1e4,编号不超过1e4。Solution一上来想到了二分图匹配,但是如果是用花瓶直接与台柱匹配,在两边编号几乎相同的情况下边数会达到1e8,因此要优化建图,用编号与花瓶匹配,这样中间的边不超过2m。具体来说,源点向编号连当连容量为前编号出现次数的边,编号向有次编号的台柱连容量为1的原创 2021-08-03 16:01:10 · 126 阅读 · 0 评论