题一
题二
题三
题一分析
知识的不全面与遗忘
革命尚需努力
组合数常用三个公式:
------(1)
-------(2)
-------(3)
预处理组合数
利用杨辉三角形,也就是性质2
for(int i=0;i<=n;++i) c[i][0]=c[i][i]=1;
for(int i=2;i<=n;++i)
for(int j=1;j<i;++j)
c[i][j]=(c[i-1][j]+c[i-1][j-1])%P;
求解逆元
由于这道题的模数是1e9+7,是个质数,所以我们可以用费马小定理求解
但要是模数不为质数,且a与mod互质,就可以用扩展欧几里得求解
当然当数据范围在可以承受之内的时候,我们也可以线性求解
题二分析
由题可知,每个点的入度只能也必须为 1 ,出度>=0
那这很显然就是一个环套树,当然也可能存在多个环套树
所以我们要求解的就是一个环套树森林
因为要求代价最小,所以我们可以利用类似Kruskal算法的思想,边权最小的边一定是属于最优方案的
就按边权从小到大加边,维护环套树森林
怎么维护环套树森林呢?
如果现在加入的这条边的两个端点:u,v
这两个端点,一个属于树,一个在环里,显然选这条边后,原图仍是一个环
一个属于环,另一个也属于环,显然这条边是不能选的(否则就不满足入度为1了)
一个属于树,另一个在另一个树里,选了过后,仍是一颗树
两个同属一颗树,则现在这棵树会变成一个环
用并查集维护一下当前这一坨是属于树还是环即可
题三分析
没有注意数据范围的提示,每个节点膜拜的长者都是节点号在它之前的啊
又是一道主席树……主席树真是厉害了,感觉无所不能,所向披靡
其实考场上也想过哈希,但不知道为什么居然没有深入进行思考
由于比较的话,1e5长度的串还有1e5个,自然不可能直接搞
所以现在我们的瓶颈就是如何快速比较两个串的大小,由于每次只会修改和膜拜的长者之间的一个字母
这种每次和之前的状态都只有一小部分不同的,我们就可以思考一下主席树
我们就可以想到哈希二分的方法。其实就是不断的询问字符串的某一部分的哈希值。
我们可以用线段树来维护哈希值,那么每次修改一个位置只需要把父亲的线段树改一个位置。 就又可以利用主席树来维护,比较的时候也从主席树的两个根开始递归比较,可以做到 O(nlog2n)
还有一点用hash的话最好用unsigned long long,自然溢出。