- 博客(56)
- 收藏
- 关注
原创 数论
突然发现之前学的算法有很多已经只是耳熟了,所以想要复习复习,水平有限,有错的还望指正Q^Q快速幂当我们算2n时,有什么方法呢,首先最先想到的是我们可以直接暴力,一个for循环直接从1不断乘2,最后得到答案int a=1,b=2;for(int i=0;i<n;i++){ a*=b;}不过如果n变大了怎么办,如果n达到1e9的规模,那就不能在规定的时间算出来了,此时快速幂的作用就来了。快速幂顾名思义就是幂运算非常快,我们可以将2n的幂也就是n用二进制分割出来,假如n为27,其二进制为1
2021-04-20 22:40:33
202
1
原创 Codeforces Round #700 (Div. 2) E. Continuous City
传送门题目大意有n个城市,构造一个图,从1到n的所有路径长为l到r且不重复题解这位大佬的题解非常good,膜拜大佬Orz大佬传送门魔改的代码#include<cstdio>const int MAX=1e6+5;struct node{ int from; int to; int value;};node ans[MAX];int ansn;int rnum[MAX],rn;int two[MAX];int main(){ int l,r; scanf("
2021-04-18 22:53:04
134
原创 Codeforces Round #700 (Div. 2) D2. Painting the Array II
传送门题目大意和上个题的唯一区别是,这个题要让数组和尽量小题解和前一天差不多,只不过判断条件改改就好了,还是看代码吧,Q^Q我的语言描绘能力太差了#include<cstdio>const int MAX=1e5+5;int a[MAX];int loc[MAX],next[MAX];int anum,bnum;int ans;int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scan
2021-04-18 22:36:25
83
原创 Codeforces Round #700 (Div. 2) D1. Painting the Array I
传送门题目大意有n个数字,可以将他们分别放在两个数组中,数组元素的个数为合并相邻元素相同的值,比如会变成题解贪心的选取,假如数组a的最后一个元素为x,数组b的最后一个元素为y,如果在原数组中x的下一个相同的数字在i,y的下一个相同的数字在j,i在j前面的话,就把数字放在b后面,分之把数字放在a后面#include<cstdio>const int MAX=1e5+5;int a[MAX];int loc[MAX],next[MAX];int anum,bnum;int
2021-04-18 22:27:53
89
原创 Codeforces Round #700 (Div. 2) C. Searching Local Minimum
传送门题目大意这是个交互题,一开始我们只知道一个n,让我们找出局部最小值的索引题解我们可以读入下标为i-1,i,i+1的数组中的值,如果a[i-1]<a[i],我们的局部最小值在i的左边一定存在,就在左半个区间中继续寻找,如果a[i]>a[i+1],局部最小值就在右边,如果两种情况都没有,那下标i对应的元素就是局部最小值#include<cstdio>int main(){ int n,m; scanf("%d",&n); int l=1,r=n+1,mid
2021-04-16 18:09:28
93
原创 Codeforces Round #700 (Div. 2) B. The Great Hero
传送门题目大意有n个怪,每个怪都有血量和攻击力,还有一个英雄,英雄每次攻击怪,双方都会扣掉和对方攻击力值相同的血,血量小于等于0,就代表死了,问英雄是否最后能杀死所有怪题解我们只用最后攻击一次攻击力最高的那个怪就好了,如果在攻击他最后一次之前还活着,证明英雄可以杀光他们#include<cstdio>#define MAX 100005long long ab[MAX][2];int main(){ long long T,n,a,b,max,c,d,dao; bool fl
2021-04-16 18:00:15
55
原创 Codeforces Round #700 (Div. 2) A. Yet Another String Game
传送门题目大意有一个字符串,Alice先手,每一次两个人都可以把之前未被修改的字符改成任意和此时字符不相同的字符,Alice希望字符串的字典序尽量小,Bob希望字符串的字典序尽量大,输出改后的字符串题解从前往后遍历,如果该Alice,就将此时的字符改为a,如果已经是a了,就改成b,如果到了Bob,就将此时的字符改为z,如果已经是z了,就改成y#include<cstdio>char str[55];int main(){ int n; scanf("%d",&n);
2021-04-16 17:51:19
57
原创 Codeforces Round #695 (Div. 2)
所有题目汇总A. Wizard of Orz题解传送门B. Hills And Valleys题解传送门C. Three Bags题解传送门D. Sum of Paths题解传送门E. Distinctive Roots in a Tree题解传送门
2021-04-14 00:14:50
69
原创 Codeforces Round #695 (Div. 2) E. Distinctive Roots in a Tree
传送门题目大意有n个点,如果其中一个点想成为独特根,那他每个路都不能有相同的值,有几个这样的独特根题解先任意设一个根,如果其中一个点a,他的子树中的点b有与a的值相同的值,那除了他的子树,其他的点为根,一定会有路经过a和b,所以除了他的子树,其他所有点都不行,反之,如果有非子树的点的值和a的值相同,那a的子树所有点也都不可取,为了快速标记,我们使用树上差分+dfs序,我的理解是后者为了方便最后的和值操作,而且标记子树也比较方便#include<cstdio>#include<v
2021-04-14 00:03:50
75
原创 Codeforces Round #695 (Div. 2) D. Sum of Paths
传送门题目大意有n个位置,机器人可以在任何位置出发,然后必须走k步,每次走可以往左或往右走一步,将路径的值加起来,就是此次走路的价值,算所有路的价值总和题解我们设dp[i][j]为用i步走过多少次j,首先我们不考虑中间经过j的次数,只算最终到j的情况,显然是dp[i][j]=dp[i-1][j-1]+dp[i-1][j+1],而中间经过的次数为dp[k-i][j]*dp[i][j]的和,及花i的步数走到j,再花k-i步走过j,之后只用将每个点的值乘每个点经过的次数的值加起来就是答案了#includ
2021-04-13 23:27:08
74
原创 Codeforces Round #695 (Div. 2) C. Three Bags
传送门题目大意有三个包,我们可以将其中一个包的a拿出来,然后将另一个包的b拿出来,再将a减去b然后放会a的包,计算最后只有一个包有一个值a,其他包为空的情况下,a的最大值题解首先我们发现,如果把数往一个包装时,如果此数的换包次数为奇次,那么此数最终的值为负数,如果此数的换包次数为偶数,那么此数最终的值为正数,所以我们可以将一个包中的元素先放到另一个包中,再放到最终的包,那么还有个问题,我们放元素时,需要借助一个值,因为题目所述必须将a-b放回a,所以分别找到三个包中的最小值a,b,c然后找其中的两个
2021-04-13 23:05:07
64
原创 Codeforces Round #695 (Div. 2) B. Hills And Valleys
传送门题目大意如果ai-1 > ai && ai < ai+1那么就会形成一个山谷,如果ai-1 < ai && ai > ai+1那么就会形成一个山顶,我们可以随意的将其中一个数改成任意值,找出山谷和山顶总量和的最小值题解我们先用一个数组来记录哪个是山顶或山谷,然后一个一个试着改他们就好了,当我们改了i之后,i-1、i+1为中心的山顶或山谷都有可能改变,所以要重新算一下就好了#include<cstdio>#include&l
2021-04-13 22:41:56
88
原创 Codeforces Round #695 (Div. 2) A. Wizard of Orz
传送门题目大意有n个数字板,我们可以选择其中一个暂停,然后其相邻的数字版会在下一秒暂停,然后是相邻数字板的相邻数字板暂停,然后…一直传递直到所有数字板都暂停,数字板一开始数字全部一样,并且所有板都是每过一秒加一,加到9之后就变成0题解我们必然要让第一位是9,这样第二位只能是8,但是我们的第三位能成为9,所以我们让第二位在8时暂停,这样第一位和第三位都是9了,之后按照9 8 7 6 5 4 3 2 1的降序输出就好了#include<cstdio>int main(){ int t,
2021-04-13 22:31:38
63
原创 Codeforces Round #703 (Div. 2) E. Paired Payment
传送门题目大意一次必须走两步,并且所需的花费是两条路的价值和的平方我们要找出1到其他点的最短花费,如果没法走到就为-1题解如果不是价值和的平方,就变成了单源最短路问题,多记录一下是否是偶数节点就好了,但是非常腌臜,他不按套路出,所以我们就需要另一个值,到此点的路的长度,就是此点和上一点的距离,这样我们才能计算这个点到后面点的花费,所以我们可以开个三维数组,第一维代表点,第二维代表上一点到此点的距离,第三维代表是奇数点还是偶数点,因为每次走两步,奇数点对答案没有意义#include<cst
2021-04-13 00:08:15
67
原创 Codeforces Round #703 (Div. 2) D. Max Median
传送门题目大意给我们一个长为n的数组,我们要找到其中长度至少为k的连续元素的排序过后的最大的中位数题解我们看到n是2e5,而且数组元素的最大值也是2e5,那我们可以二分查找答案,假如我们现在有查找mid=(1+n)/2是否存在,我们可以将数组中大于等于mid的元素记为1,小于mid的元素记为-1,我们可以从前往后找,因为我们找的是最大的中位数,所以我们要让区间中数字尽量大,这样能保证中位数也大,所以我们要找到区间中正数和最大的情况,然后和0比较,如果大于0,证明此时的mid小了,要更大,所以区间变为
2021-04-13 00:07:59
68
原创 Codeforces Round #703 (Div. 2) C2. Guessing the Greatest (hard version)
传送门题目大意和C1一样,只不过询问次数从40次降到了20次题解我们第一步可以模仿C1的方法,得到最大值所在的区间,假如次大值在i,询问1到i的次大值是否在i,如果在i再询问i/2到i的次大值是否为i,如果是,证明最大值就在i/2到i位置上,继续如此不断二分,就能得到答案,大约在18次左右就那找到答案#include<cstdio>int main(){ int n,ans,nowq,l,r; scanf("%d",&n); printf("? %d %d\n",1,n
2021-04-13 00:07:42
81
原创 Codeforces Round #703 (Div. 2) C1. Guessing the Greatest (easy version)
传送门题目大意有n个数,我们可以输入?l r,将得到l到r次大值的下标,我们可以问40次,找出数组中的最大数的下标题解我们可以先询问1到n的次大值下标a,如果a在1到n/2之间,然后询问1到n/2的次大值下标b,且a等于b,显然最大值在1到n/2之间,如果a不等于b,显然最大值在n/2到n之间,如果a在n/2到n之间,也是类似的推导过程,所以我们可以每次将区间用此方法二分,n的值是1e5,我们每次二分区间需要2次询问,所以需要2log(1e5)=34次多询问#include<cstdio&g
2021-04-13 00:07:21
91
原创 Codeforces Round #703 (Div. 2) B. Eastern Exhibition
传送门题目大意有n个房子的坐标,我们要建一个展览会,距离n个房子的总距离最近,距离计算方法为|x1−x2|+|y1−y2|题解我们发现距离计算方法和我们平时的方法不太一样,这个方法可以将每个房子的x和y坐标直接分开计算,总值不会变,我们可以将n个房子距离展览会的x值和y值的差分别计算起来,将x和y分别排序,只要将x中间值和y的中间值的差相乘就是可以建展览会的地方的可能情况了,比如x的值为1 2 5 9,y的值为3 4 9 10,那我们的值就为(5-2)*(9-4)#include<cstdi
2021-04-12 17:53:26
56
原创 Codeforces Round #703 (Div. 2) A. Shifting Stacks
传送门题目大意有n堆积木,我们可以将第i堆积木移动到第i+1堆中,是否可以让这n堆积木严格递增题解我们可以直接记录第1堆大于0的数量,然后是第2堆大于1的数量…如果第i堆数量小于i-1,就将之前记录的多余的数量补上来,如果还是不够就证明无法严格递增#include<cstdio>int main(){ long long t,n,a,sum; bool flag; scanf("%lld",&t); while(t--){ sum=0; scanf("%lld
2021-04-12 17:38:12
63
原创 Codeforces Round #708 (Div. 2)
所有题目汇总A. Meximization题解传送门B. M-arrays题解传送门C1. k-LCM (easy version)题解传送门C2. k-LCM (hard version)题解传送门D. Genius题解传送门E1. Square-free division (easy version)题解传送门E2. Square-free division (hard version)题解传送门...
2021-04-12 17:03:54
55
原创 Codeforces Round #708 (Div. 2) E2. Square-free division (hard version)
传送门题目大意和E1大意相同,只不过现在可以将k个数字改成任意数字题解我们可以从右往左进行查找,用left[i][j]记录从i开始改j个数字可以让这一段数字不同的最远的l,也就是记录最长区间l到i,这样我们可以对数组从左往右进行dp,dp的转移公式dp[i][j]=min(dp[i][j-1],dp[left[i][lst]][j-lst]+1);#include<cstdio>#include<algorithm>using namespace std;const
2021-04-12 16:54:28
69
原创 Codeforces Round #708 (Div. 2) E1. Square-free division (easy version)
传送门题目大意将一个有n个正整数的数组切分为数个数组,要求新的数组内元素两两相乘不能是完全平方数题解将n个数进行质因数分解,如果质因数的数量为偶数个,舍弃,如果质因数数量为奇数个,那么就保存一个,例如500,有2个2,3个5,那么我们将其变为5,这样从前往后遍历数组,如果每个段中有相同元素,分割成新段就好了,因为相同的数会组合出完全平方数,注意不能直接找出现次数最多的数当答案,因为可能有5 5 5 2 2 2 5这种情况#include<cstdio>#include<map&
2021-04-12 16:21:11
85
原创 Codeforces Round #708 (Div. 2) D. Genius
传送门题目大意有n个题,从前往后的复杂度Ci为2的i次方,我们如果刚解决问题j,想要解决问题i,就要满足的IQ<|Ci-Cj|,解完i后,IQ就会变为|Ci-Cj|,并得到|Si-Sj|分,刚开始IQ为0,我们可以先解任意一个题,一个题可以解决多次,我们要得出最多可以有多少分题解因为复杂度是2的i次方,所以我们解完i题后,我们只能往前解决一个问题后,就不能再往前找了,比如有4个题1 2 3 4,我们解决3后,可以跑到2,但是不能再从2跑到1,因为IQ不允许,此时我们只能往后跑,从2跑到4,我们
2021-04-12 02:33:09
96
原创 Codeforces Round #708 (Div. 2) C2. k-LCM (hard version)
传送门题目大意和C1唯一的区别是k现在不只是3,还可以大于3题解我们将n分出来k-3个1,然后问题又转换成了C1#include<cstdio>int main(){ long long T,n,k; scanf("%lld",&T); while(T--){ int flag=1; scanf("%lld%lld",&n,&k); while(k>3){ if(flag){ printf("1"); flag=0
2021-04-12 01:54:17
127
原创 Codeforces Round #708 (Div. 2) C1. k-LCM (easy version)
传送门题目大意给我们n和k,k为3,我们需要将n分成3个数,且此3个数的最小公倍数不能超过n/2题解如果n为奇数,那么我们可以将其拆分为1,n/2,n/2如果n为偶数,如果n/2为奇数,那我们可以先提出来一个2,让剩下的数可以对半分而且是2的倍数,分成了2,(n-2)/2,(n-2)/2,如果n/2为偶数,那么我们可以先提出来一半,剩下的对半分还是2的倍数,分成了n/2,n/4,n/4#include<cstdio>int main(){ long long T,n,k; sc
2021-04-12 01:51:02
106
原创 Codeforces Round #708 (Div. 2) B. M-arrays
传送门题目大意将数组以任意顺序划分为数个数组,满足新数组中任意两个相邻元素的和是m的倍数,找数组的最少数量题解我们可以将每个数和m取余,如果是0,那么所以0可以放一起,因为他们任意两个数加起来都是m的倍数,如果是m/2并且m是偶数,也可以放一起,他们任意两个数加起来依然是m的倍数,其他的要匹配,如果是1,就和m-1匹配,形成1 m-1 1 m-1…的数组。#include<cstdio>#include<algorithm>#include<map>#in
2021-04-12 01:43:30
133
原创 Codeforces Round #708 (Div. 2) A. Meximization
传送门题目大意将给定的n个数排序,并使下面式子最大化题解emmm排个序就好了,将重复的元素放最后,前m个不同数从小到大输出。#include<cstdio>int num[105];int main(){ int T,n,m,flag; scanf("%d",&T); while(T--){ scanf("%d",&n); flag=1; for(int i=0;i<n;i++){ scanf("%d",&m); num
2021-04-12 01:28:43
77
原创 Codeforces Round #704 (Div. 2)
所有题目汇总A. Three swimmers题解传送门B. Card Deck题解传送门C. Maximum width题解传送门D. Genius’s Gambit题解传送门E. Almost Fault-Tolerant Database题解传送门
2021-04-10 22:31:21
56
原创 Codeforces Round #704 (Div. 2) E. Almost Fault-Tolerant Database
传送门题目大意有n个长为m的数组,我们要找出一个数组a,和之前n个数组比较,每次不能有超过两个数字不同,如果找不到输出No题解我们直接暴力就好了,将第一个数组当作我们的答案,然后从第二行开始比较,如果不同的数量超过了2个,我们尝试递归的修改就好了,如果和数组a不同的数量有3个,那么我们可以选择将一个或两个不同的数字都匹配为a的数字,如果一个数字匹配了,那我们还可以再修改一个数字,与其他的不同数量有3个的数组匹配,如果和数组a不同的数量有4个,我们任意选2个匹配,匹配完之后,再搜索一遍全部的数组,如果
2021-04-10 22:19:30
75
原创 Codeforces Round #704 (Div. 2) D. Genius‘s Gambit
传送门题目大意我们有a个1,b个0,我们要构成二进制数x和y,并且都花费a个1和b个0,并且x,y不存在前导0,计算x-y并让他们的结果有k个1题解因为没有前导0,所以x和y开头皆为1,我们为了结果有尽量多的1,假设我们有两个1和3个0,我们发现可以另x,y为下值x:11000y:10001这样我们可以让他们的差的1尽量多,而相同位置的1相减之后的效果和相同位置都是0一样,比如x:11010y:10011x-y和我们之前的值一样所以我们得到了计算最多1的方法,及a+b-2,如果k小于等
2021-04-10 21:44:40
106
原创 Codeforces Round #704 (Div. 2) C. Maximum width
传送门题目大意有两个字符串分别长为n和m,n大于等于m,找出一个n的子串等于m,找出子串的相邻元素在原数组的下标的最大距离题解emmm这个题题目说的挺清楚,按照题目说的找就行了#include<cstdio>#include<algorithm>using namespace std;const int MAX=2e5+5;char s[MAX];char t[MAX];int front[MAX];int last[MAX];int main(){ in
2021-04-10 21:29:29
55
原创 Codeforces Round #704 (Div. 2) B. Card Deck
传送门题目大意我们有一落牌,从下往上编号,及最底下的牌是1号,最上层的牌为n号,我们每次可以选任意多的牌,将这些牌不改顺序的放在新牌堆上,不断执行此操作,直到原始牌堆没有牌了。牌堆的值的计算方法为我们需要让新牌堆的此值最大,输出新牌堆的从下往上的牌题解我们分析一下式子,当i越小,pi的项越大,所以如果我们把最大的牌放最前面显然可以让此值最大,所以我们只需要从后往前找最大的牌,然后输出这些牌,再找剩下的牌最大的牌,不断重复,直到全部输出就好了#include<cstdio>#inc
2021-04-10 21:15:24
85
原创 Codeforces Round #704 (Div. 2) A. Three swimmers
传送门题目大意我们在第p分钟在水池的左边等候,有三个人在0时刻从水池的左边开始游,分别花费a,b,c时间游一个来回,及从左边游到右边再游回左边需要花费a,b,c的时间,问我们最长等多长时间可以遇见三人中的一人。题解暴力就好,计算等三个人要花的时间,选中最小时间就行了#include<cstdio>int main(){ long long t,p,a,b,c; scanf("%lld",&t); while(t--){ scanf("%lld%lld%lld%lld
2021-04-10 21:03:01
56
原创 Codeforces Round #706 (Div. 2)
所有题目汇总A. Split it!题解传送门B. Max and Mex题解传送门C. Diamond Miner题解传送门D. Let‘s Go Hiking题解传送门E. Garden of the Sun题解传送门F. BFS Trees题解传送门
2021-04-09 23:23:20
49
原创 Codeforces Round #706 (Div. 2) F. BFS Trees
传送门题目大意机翻的效果还不错,这里直接把有道的机翻搞过来了。我们定义一个图的生成树是一个以顶点s为根的BFS树,当且仅当对于每个节点t,图中s和t之间的最短距离等于生成树中s和t之间的最短距离。给定一个图,我们定义f(x,y)为该图中同时根为x和y的BFS树的生成树的数目。给定一个有n个顶点和m条边的无向连通图。对所有i j,计算f(i,j),并对998244353取模题解我们先对每个点跑一遍最短路,得到数组dis[i][j],以i为根到j的距离,接下来i,j,k三层循环,外层两个循环代表以
2021-04-09 23:09:35
86
原创 Codeforces Round #706 (Div. 2) E. Garden of the Sun
传送门万万没想到,这个题这么暴力,还是我太菜了Q^Q题目大意输入一个n行m列的矩阵,X为空地,*为向日葵,让我们随便砍向日葵,值到所有X连起来,且任意两个X之间只有一条路,也就是X不能成环,输入的矩阵中,X附近的8个相邻格都不会有X,此题一定有方案,如果方案不唯一,随便输出一个就好,输出砍完向日葵后的矩阵图,我们不需要最小化砍掉的向日葵的数量题解因为X的相邻8个方向都没X,所以我们可以直接每隔两列,砍一列,比如形如X.X. . .. . . .X.X.X. . .我们可以砍成X. X.
2021-04-09 20:32:39
77
原创 Codeforces Round #706 (Div. 2) D. Let‘s Go Hiking
传送门题目大意给n个不同的整数n,刚开始,Qingshan 可以选一个数a, Daniel 可以选择一个数b,之后Qingshan 先走,Qingshan 可以选择移动到在数组中与数字a相邻的且小于a的数,Daniel 可以选择移动到在数组中与数字b相邻的且大于b的数,并且a和b不能相等,问可以让Qingshan获胜的a的个数,获胜条件为此时该Daniel 走,且Daniel 无处可走题解我们可以找最长的单调序列,因为显然单调序列越长,可以走的步数越多,获胜的可能越大。如果最长的单调序列数量有3个
2021-04-09 19:58:28
66
原创 Codeforces Round #706 (Div. 2) C. Diamond Miner
传送门题目大意矿工在y轴,钻石在x轴,每个矿工只能采一个钻石,采矿时要花费sqrt(xx+yy)的能量,要我们花费最少的能量题解将矿工们和钻石分别排序,可以试着画图,只有在离原点第k个位置的矿工来挖第k个钻石,才能让线段不交叉,他们形成的线段和才能最小#include<cstdio>#include<algorithm>using namespace std;const int MAX=1e5+5;int x[MAX];int y[MAX];int main()
2021-04-09 17:47:26
79
原创 Codeforces Round #706 (Div. 2) B. Max and Mex
传送门题目大意给我们一个由n个不同的非负整数组成的multiset S,将元素⌈(a+b)/2⌉(四舍五入)添加到S中,其中a=mex(S), b=max(S)。如果这个数字已经在集合中,它将被再次添加。multiset的max表示multiset中的最大整数,而multiset的mex表示multiset中不存在的最小非负整数t,例如mex({1,4,0,2})=3;mex({2,5,1})=0.我们要找出计算k次操作之后S中不同元素的数量。题解如果mex(S)小于等于n,证明我们前n个数
2021-04-09 17:25:26
84
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人