problem 1 从1~n里选出一些数乘起来构成完全平方数,求能得到的最大完全平方数,结果对1e9+7取模,n<=106 思路 如果从判断哪些能选这个角度来做这个题那么就会陷入死胡同,不妨看哪些不能选,把n!表示成小于等于n的质数的幂的乘积,然后对于幂为奇数的,需要去掉一些数让它的幂变成偶数,怎么去呢?去掉这个质数就ok。那么问题就是对于n!=pc11pc22...pctt统计每个ci的大小(奇偶)。 对于一个pi的每一个pki(1<=k<=c1),求∑[1<=x<=n][gcd(x,pki)=pki],而它等于npki−npk+1i,所以ci=∑k(npki−npk+1i)[pki<=n],复杂度为O(nlogn∗logn)=O(n)。 problem 2 给n个数a1~an和L,R,随机选择一个区间[l,r](l<=r),求区间中数的平均值在[L,R]之间的概率,n<=106 思路 实际上就是求区间平均值在[L,R]之间的个数。而[L<=x<=R]=[1<=x<=R]−[1<=x<=L−1],求区间平均值小于等于某个数R的区间个数即可。把所有数都减去R,转化为求区间和小于等于0的区间个数。令sum0=0,sumi=∑ak[1<=k<=i]那么就是求满足sumj>=sumi,0<=j<i<=n的个数,而这个可以利用平衡树在O(nlogn)的时间内求出来。更好的办法是将所有的sum排序,然后用双指针快速统计,复杂度O(n)。 problem 3 有一张长度为n的纸条,从左至右编号为0~n,给出m个数,表示每次折叠的位置,求经过m次折叠后纸条的长度。n<=1018,m<=1000 思路 每折叠一次,对纸条重新编号,然后更新长度和后续未完成的折叠位置在新的编号规则下的编号。这样复杂度为O(m2)。