1.
n个小于等于10000的数,问两两之间的最大公约数的总和。难点在于两个数有多个公约数,不是最大的公约数会重复统计,这可以从大到小统计公约数为x的对数,对于公约数为x的,要减去公约数为x的倍数的对数,就是类似筛素数的方法枚举倍数。
2.
m组人,总共n个人,坐到n个位置中,同一组人不能相邻,问方案数。dp[i][j]表示前i组有j个不合法间隙。转移就是,第i组有x人来说,枚举这x人分成几组,插入到间隙中,当前有t人,间隙就有t+1个,包括左右端,x人分成h组有c(x-1,h-1)种方案,这也是间隙隔板法求出来的,枚举j组插入到k个合法间隙,h-k个不合法间隙,然后这h组会产生新的x-h个不合法间隙,转移看出来了吧。复杂度好像是3次方的。最后答案是dp[m][0]。
3.
http://codeforces.com/contest/538/problem/F
好像很多解法,睡前想了下,最土的就是把所有区间处理出来,nlogn级别的区间个数,然后用函数式线段树统计每个区间比某个数大的数有多少个。我脑子有坑,傻逼啊,刚看到了个解法,树状数组,仔细一想,这用个P的函数式线段树,排序下树状数组不就完了?
看了某sjtu神牛的代码发现可以分情况,sqrt(N)*N的做法。对于编号小于sqrt(N)的节点,其区间每次调整不会超过sqrt(N),大于sqrt(N)的节点,其区间长度不会超过sqrt(N)。
看了某UESTC神牛的做法,思路好像是对于每个点,对于一段连续的k值其父节点是不会变的,所以就对每个点处理其所有可能的父节点并且对对应的那段k进行更新,这可以直接用个sum数组O(1)维护。这复杂度不好算啊,看运行时间,比N*sqrt(N)的和N*logN*logN的慢很多。
DP数学题不好练啊,这方面真是废了,拿手的数据结构题也不能一下反应过来了,只有代码速度、准确度还好一些。