151031的测试总结

来源:互联网 发布:淘宝店铺装修素菜 编辑:程序博客网 时间:2024/06/05 16:38

第一题

【题目及题号】prime superoj981
【题解】
题意大概就是要求一组数当中任意两个数之间互质,n个数最少分成多少组?在分成最少组数的情况下,最小化最大数组元素个数。
转化一下本体就是求团,那么这种经典模型就可以搜索啦。
对于当前点,看能不能把它放到前面的集合中去,每次只对集合中的数进行验证。
如果存在一个数满足其和x的gcd不为1,就不能放入。
然后再把当前点放到一个新的集合看能不能深搜出更优的解。
只用减一个枝,当前集合数量如果已经大于ansa就返回。

注意一定要把当前点变成新集合的放在后面,因为前一种方式出现更优解的可能性应该比较大。

【易错点】

注意phi(1)就是1,所以不能特判相等的情况!

第二题

【题目及题号】isfind superoj982
【题解】
本题要求询问当前字符串在所给母串中是否出现子序列。
我的作法是对于当前i记录一个f[i][j]i右侧字母j最近出现的地方。
然后n*26就可以预处理出来。
最后直接跑一跑就可以了。
另外有人是直接记录的每个字母出现的位置,然后每次询问是二分查找的。
【注意】
考试的时候以为是个匹配问题,差点下手写kmp,还好发现了题目理解错误。

第三题

【题目及题号】divide superoj983
【题解】
给出n个数,求三元组ai,aj,ak的数量。(ai*aj*ak%p==0 且i < j < k)
性质一:每个数对mod p产生贡献的部分是gcd(ai,p)
性质二:我只要选出三个数,任意两个下标不相同,那么他们自然存在先后顺序。
我们可以用fac[]记录p的因数,cnt[i]记录所有数与p的gcd为因数i的数量。(保证每个数只会被统计一次)
然后就可以枚举因数,
情况一:fac1*fac2*fac3%p==0 ans+=cnt1*cnt2*cnt3;

情况二:fac1*fac1*fac2%p==0 ans+=(2cnt1)cnt2;

情况三:fac1*fac1*fac1%p==0 ans+=(3cnt1);
【注意】
本来是为了防止炸long long
写成

ans += cnt[i] * (cnt[i]-1)/6 * (cnt[i]-2); 

然而前面那一部分先除以6可能是除不尽的。
所以要最后除以6。

ans += cnt[i] * (cnt[i]-1) * (cnt[i]-2)/6;
0 0
原创粉丝点击