常州培训 day7 解题报告

最后一天。。有些感慨,这七天被虐的感动万分

第一题:

题目大意:

求出 n*i(i=1,2,3....n) mod p的逆元  n<p<=3000000 ,p是质数。

之前写过了,懒得再写了。链接http://www.cnblogs.com/vb4896/p/3911283.html

第二题:

题目大意:

给区间染色,一种颜色会覆盖另外一种,且区间的端点也算一种颜色。比如 [2,3] 染成红色,[1,2]染成绿色,[3,4]染成紫色,询问区间[2,3],那么会有红绿紫三种颜色。

颜色用数字表示,颜色种数k<=60,颜色从0开始编号。有q个操作(q<=500000),要么询问一个区间的颜色种数,要么染色。

解题过程:

1.一看就是考线段树,poj上原题的改版,那题是端点不算颜色的,处理起来方便得多。

2.对于线段树上的每一个节点,维护一个cover(long long),用二进制压位的方法保存某种颜色是否染过(0,1);更新的话只要 它的所有儿子的cover  用或运算 。

3.考试的时候1个小时写好,调试了2个小时。。对线段树加了些特殊处理的情况,最后发现自己出的一组小数据过不去。然后才发现 对于点修改,我的线段树是要挂掉的。。 本来以为要爆0,结果测试数据中没有点修改的情况。。骗到了AC。

4.考后思考:其实可以 建2棵线段树,一个是只管端点,一个是只管线段,写起来几乎一模一样,复制粘贴就好。询问的时候只要 对询问两棵的结果 做或运算即可。自己也写了下,20分钟写好,调试了一个小时。。看了半天发现又是老错误,就是

1<<c  的时候 ,c不能超过30,因为1默认是一个int。 所以要改成(long long )1<<c  或者 1LL << c ;

5.讲课大神提供的标准解法:个人感觉非常巧妙, 把 一条长度为1的线段 拆成 3个点,也就是2个端点,把中间的线段看成一个点。  把线段树的规模扩大了一倍,但是处理起来非常方便。

第三题:

题目大意:

给出一棵n个节点的树(n<=50000)假设在一棵有根树上存在五个互不相同的节点,分别记为a,b,c,d,z,若这5 个点同时满足以下要求:a,b,c,d,lca(a,b),lca(c,d),lca(lca(a,b),lca(c,d))这7个节点互不相同,并且z是lca(lca(a,b),lca(c,d))的祖先;那么五元组(a,b,c,d,z)表示了一棵合法的“不三不四树”。同时,交换

a,b,c,d,z的顺序只算作一种。 求方案数mod 1234567891;

解题过程:

1.这题考试时感觉会很难,就把时间放在了第二题。爆搜都写不出来。算法比较容易理解,有个优化非常关键。

2.AC算法:

定义F[node,0]为以node为根的子树的节点数;

定义F[node,1]为以node为根的子树中 ,选出3个不同节点a,b,c,且LCA(a,b)=c 的方案数(不考虑顺序,下同)

定义F[node,2]为以node为根的子树中,选出4个不同节点a,b,c,d,且LCA(a,b)=LCA(c,d)=node的方案数;

A : F[node,0]最好转移,累加F[node.son,0] 再加1;

B : F[node,1]=sum ( F[i,0]*F[j,0]),(i<j  i,j∈node.son); 这里的<表示i在j的左边,下同

C : F[node,2]=sum ( F[i,1]*F[j,1]),(i<j  i,j∈node.son);

这样的话复杂度应该是O(N^3);

优化:在B中的sum ( F[i,0]*F[j,0]) 这里, 这里其实不必一一枚举 i,j,对于一个固定的j,那么 要加上F[i,0]*F[j,0];

i取遍 j左边的所有儿子, 利用乘法分配率, 其实只要 F[j,0] * sum(F[i,0]) (i<j  i,j∈node.son);sum只要边求边维护即可。 同理 C 也用同样的方法优化 总的复杂度优化到 O(N);

上一篇:Ruby测试小代码[计算50以内的素数]


下一篇:tomcat集群和负载均衡的实现(session同步)