首页 > 代码库 > 省常中模拟 day2
省常中模拟 day2
第一题:
题目大意:
有mn颗糖,要装进k个盒子里,使得既可以平均分给n个人,也可以平均分给m个人。 求k的最小值。
解题过程:
1.先看一组小数据(13,21).那么根据贪心的原则很容易想到先拿13个盒子,每个盒子装13颗糖,这样当要分给13个人的时候,每个人还欠8颗糖,当要分给21个人的时候,还有8个人欠13颗糖.所以问题就变成了把8*13颗糖放到盒子里,要求既可以平均分给8个人,也可以平均分给13个人。 也就是说可以不断减小问题的规模:
(13,21)->(8,13)->(5,8)->(3,5)->(2,3)->(1,2)->(1,1)
2.观察上面的过程,和辗转相减求最大公约数的过程一模一样。但是仅仅是相减效率就不高了,所以可以变成辗转相除。对于数据(x,y) 每个盒子最多只能装min(x,y)颗,所以这样的装法一定是最优的。
3.题解里说最小盒子数量k=n + m - gcd(n,m)。
证明:考虑一个n 个黑点、m 个白点的二分图,第i 个黑点表示第i 个小朋友(总人数为n 时),第j 个白点表示第j 个小朋友(总人数为m 时);一条边(i,j) 表示这样一个盒子,这个盒子在人数为n 时属于第i 个小朋友,在人数为m 时属于第j 个小朋友。考虑这个图的某一连通分量,它包含x 个黑点,y 个白点,则此连通分量中的边所代表的盒子的糖果总数= xm = yn,于是x n/ gcd(n,m),即每个连通分量至少包含n/ gcd(n,m)个黑点,于是连通分量数量不超过gcd(n,m),所以边数至少为n + m - gcd(n,m).
初始得分100.
第二题:
题目大意:
在N个点M条边的无向图中,给出q个询问(A,B,P),求从A到B mod P 意义下的最短路的长度。
N,M,q<=50000.
解题过程:
1.这题真心神题,一点思路都没有,直接告诉我这绝对不是图论题而是数学题。直接暴力打了个spfa,拿到了35分。
2.直接贴官方题解吧,暂时还没看明白:
第三题:
题目大意:
给出一个长度为N的字符串,有q个询问(L,R),求区间[L,R]中有多少个子序列“gcd”。
N,q<=80000
解题过程:
1.70分是很好拿的(N,q<=4000),只要在区间里找出所有的c,然后就可以利用前缀和搞出它前面的g和后面的d的个数,根据乘法原理统计即可。 找出区间里所有的c,我加了个二分查找的优化,对于完全随机的数据(c的个数比较少)效率比较理想,但还是只能拿到70分。
2.莫队算法:先分块,然后把所有询问排序(左端点在同一个块里的按右端点排序,不在同一个块里的按左端点排序).根据询问区间的变化来维护g,c,d,gc,cd,gcd的个数。 效果比较理想,最慢的点只要500ms左右。
3.O(N+q)的神算法:先处理处g,c,d,gc,cd,gcd的前缀。
[L,R]里的gcd个数=[1,R]的gcd的个数-[1,L-1]里gcd的个数-[1,L-1]里g的个数*[L,R]里cd的个数-[1,L-1]里gc的个数*
[L,R]里d的个数。
而[L,R]里cd的个数又等于[1,R]里cd的个数-[1,L-1]里c的个数*[L,R]里d的个数-[1,L-1]里cd的个数。
所有的东东都可以用前缀和来得到。 最慢的点只要50ms.
省常中模拟 day2