😊 | Powered By HeartFireY | MINIEYE Contest 1 Solution |
A.Mod, Or and Everything
Problem Description
You are given an integer .
You are required to calculate .
The “or” operation means “bitwise OR”.
Input
The first line contains an integer representing the number of test cases.
For each test case, there is an integer in one line.
Output
For each test case, print the answer in one line.
Solution
😀 算法标签:打表找规律 |
读完题还是没有思路,遂打表~,找规律,打表程序和数据:
打到,规律特别明显,遂打到验证,发现规律成立:
然后写了一发AC。但是这跟题目描述究竟有何联系呢?可以对任意值而言:对其从取模,那么除去他二进制最高非0位,其模数取遍各位为1的情况(可以打表验证),那么通过题目的按位取或方式得出的结果所有位全为,正好解释了这个规律。
(其实没必要用快速幂 \doge)
E.Minimum spanning tree
Problem Description
Given points, numbered from to , the edge weight between the two points and is . Please find the minimum spanning tree formed by them.
A minimum spanning tree is a subset of the edges of a connected, edge-weighted undirected graph that connects all the vertices together, without any cycles and with the minimum possible total edge weight. That is, it is a spanning tree whose sum of edge weights is as small as possible.
is the smallest positive integer that is divisible by both and .
Input
The first line contains a single integer
The only line of each test case contains one integers
Output
For each test case, print one integer in one line, which is the minimum spanning tree edge weight sum.
Solution
😀 算法标签:前缀和、素数筛、思维/规律 |
题目给定个点,从编号,任意两点间的均有一条边,其边权为两点编号的最小公倍数,求该图的MST。
首先明确数据范围,显然不是一道跑最小生成树算法的题。那么考虑规律。
根据题目条件:边权为两点的最小公倍数,那么我们可以对点进行分类:①.质数点 ②.合数点
对于任意两个质数点,其最小公倍数必然为两质数点乘积,那么为了使边权最小,可以让所有的质数点()全部向连线,可保证所有质数点间边权最小。
而对于合数点,则向其约数点连边。此时可保证边权最小。
如此可得总边权和为 质数的和*2+合数的和。
注意开long long!
F.Xor sum
Problem Description
Given a sequence of integers of length n, find the shortest consecutive subsequence witch XOR sum not less than k.
If there are multiple consecutive subsequences of the same length, print the consecutive subsequence with the smallest left end point.
If there are no consecutive subsequence witch XOR sum not less than k, just print “-1”.
Input
The first line contains a single integer t (t<=100) representing the number of test cases in the input. Then t test cases follow.
The first line of each test case contains two integers n (1<=n<=100000) and k (0<=k<2^30), representing the length of sequence.
The second line of each test contains n integers ai (0<=ai<2^30), representing the integers in sequence.
The number of test witch n>1000 does not exceed 5.
Output
For each test case, print two integers in one line, representing the left end point and right end point of the consecutive subsequence.
If there are no consecutive subsequence witch XOR sum not less than k, print “-1” in one line.
Solution
😀 算法标签:0-1 Trie |
给定一个长度为的序列,求一段最短的连续子序列满足异或和大于等于。
序列长度范围 ,考虑使用复杂度及以下的算法解决。
首先我们需要知道:对于前缀异或和,如果要求一段区间的前缀异或,有
那么对于本题,我们对整个序列求前缀异或,则问题转为求序列内两个距离最近的数,使得他们的异或值不小于。
对于转化后的问题可以使用0-1字典树
解决。
接下来对如何使用0-1字典树
解决这个问题进行分析:
首先,我们采用类似在线处理的方式,边求异或前缀边更新最优解,这样相当于固定第二个数(也就是原题区间右端点),来求最优的第一个数(也就是原题区间左端点)。
- 首先读入当前值,求到当前值位置的异或前缀;
- 判断:如果当前的异或前缀,且当前区间长度(即为)记录的最短区间长度,则更新一次最优解;
- 求位于~当前范围内满足异或前缀的最大数(即为原题区间左端点),再次判断是否需要更新最优解;
- 将当前异或前缀插入到字典树中。
先对字典树的插入过程进行分析:
和普通字典树一样,我们使用一个数组,由于仅有两个字符,因此数组第二维度只需要两个空间,用于表示连接当前节点和子节点两条边,那么数组的使用方法可以表示为:
那么构造数组的过程就可以得出了:
- 首先判断对于待插入位,当前节点是否已经被插入过,如果被插入过,则向子节点继续走
- 如果没有插入过,那么新建节点,同时初始化两条边指向的节点为空,记录新子节点位置,向新子节点走
此外,由于我们要求最大异或值的下标,因此还需要一个额外的数组存一下下标:设表示编号为的节点对应的序列下标。由于我们要找的是尽可能大的"左端点",因此我们对于下标的存储策略是"新覆盖旧"。这里需要读者重点理解一下。
我们继续对查找区间左端点的过程进行分析:字典树上自根节点到叶节点的每条路径均表示一个二进制数,我们从根节点开始(也就是最高位开始),将待异或值对应位取出与之进行异或,加和后(此处由于是数位异或,因此是累加),继续递归向子节点移动。这个过程实际就是个DFS。
对于递归的终止条件我们需要注意:我们没有必要累加至叶节点,而只需要在遍历过程中进行判断:如果截至当前数位,先前数位相异或后累加的值已经大于等于,再向下累加一定还是大于等于,那么我们直接返回当前节点的编号即可。
此外,还要再对递归过程进行剪枝,如果截至当前数位,假设当前位到最低为全部为,将截至当前的高位异或累加值加上到低位全为仍不满足大于等于,那么无论怎么向低位求异或累加也不可能再出现再高的情形,此时直接返回表示不满足条件即可。
搜索的过程是比较简单的,只需要从当前节点开始,向左右两条边走,分别求出两个数当前位的异或值,累加至和中,向低位移动即可。
AC CODE
H.Maximal submatrix
Problem Description
Given a matrix of n rows and m columns,find the largest area submatrix which is non decreasing on each column
Input
The first line contains an integer T(1≤T≤10)T(1≤T≤10)representing the number of test cases.
For each test case, the first line contains two integers n,m(1≤n,m≤2∗103)n,m(1≤n,m≤2∗103)representing the size of the matrix
the next n line followed. the i-th line contains mm integers vijvij(1≤vij≤5∗103)(1≤vij≤5∗103)representing the value of matrix
It is guaranteed that there are no more than 2 testcases with n∗m>10000
Output
For each test case, print a integer representing the Maximal submatrix
Solution
😀 算法标签:悬线法 |
听队友说是悬线的板子题…
首先分析一下思路:大小关系只针对纵向而言,那么想到转化为0-1矩阵,但后跑悬线法板子即可。这里放个参考标程的代码,自己写的不堪入目。。。
I.KD-Graph
Problem Description
Let’s call a weighted connected undirected graph of nn vertices and m edges KD-Graph, if the
following conditions fulfill:
* nn vertices are strictly divided into KK groups, each group contains at least one vertice
* if vertices pp and qq ( pp ≠ qq ) are in the same group, there must be at least one path between pp and qq meet the max value in this path is less than or equal to DD.
* if vertices pp and qq ( pp ≠ qq ) are in different groups, there can’t be any path between pp and qq meet the max value in this path is less than or equal to DD.
You are given a weighted connected undirected graph GG of nn vertices and mm edges and an integer KK.
Your task is find the minimum non-negative DD which can make there is a way to divide the nn vertices into KK groups makes GG satisfy the definition of KD-Graph.Or −1−1 if there is no such DD exist.
Input
The first line contains an integer TT (1≤ TT ≤5) representing the number of test cases.
For each test case , there are three integers n,m,k(2≤n≤100000,1≤m≤500000,1≤k≤n)n,m,k(2≤n≤100000,1≤m≤500000,1≤k≤n) in the first line.
Each of the next mm lines contains three integers u,vu,v and cc (1≤v,u≤n,v≠u,1≤c≤109)(1≤v,u≤n,v≠u,1≤c≤109) meaning that there is an edge between vertices uu and vv with weight cc.
Output
For each test case print a single integer in a new line.
Solution
😀 算法标签:并查集 |
给定边集,要求划分为组,求一个,使得同一组的顶点间的路径最大值小于等于。
首先将给定的边集按照权值大小进行排序,初始化并查集为点集,每个点看作一个连通块,然后遍历边集合,使用并查集查询是否位于同一集合,不位于同一集合则合并点,连通块个数-1,直至下一次合并后连通块个数为时,那么此时被遍历的边的权即为答案(按照大小遍历边集,保证所有边小于等于),否则输出。
确实签到题。