一些很nice的题目/idea等

CF 1061 D. TV Shows

贪心:两条线段一定是挨的最近的连起来,感性的理解,和距离远的合一定不和近的合更优。

所以按左端点排序,将右端点放到一个set里,然后对于每个线段找小于这个线段左端点的最远的点,考虑时候合起来。

另一种方法,将每个点拆成两个,分别是左端点的点,和右端点的点,然后排序后,扫所有的点,扫到右端点加入到堆,左端点的话在堆里找最大的(最靠右的),考虑是否与它合起来。

bzoj 1070: [SCOI2007]修车

会发现一辆车的等待时间,是这个人修理的前面所有车的时间和,所以每个人的最终等待时间由于顺序不一样就不同。朴素的建图就是枚举每辆车是第几个,然后在连其他的,复杂度太大。

设ti为第i辆车的等待时间,那么ti=t1+t2+t3+...+ti(这些都是同一个人修的),总的时间就是全记起来,会发现,第一个修的t1会加n遍,t2加n-1遍,由于n不确定,所以反过来建,倒数第一个修的加一遍,倒数第二个加两遍。然后拆点最小费用最大流。

bzoj 1098: [POI2007]办公楼biu

反向图的联通块个数。n<=100000,直接建图是开不下的。在bfs的时候,一个点总是枚举他所连的所有点,然后bfs下去,瓶颈在于枚举反图中的边。可以用链表维护所有未经过的点,每次找到一个点,那么既然枚举边太大,考虑枚举反图中不连的点,即正图中连向的点,然后将这些点从链表的删掉,就是所有连向的点,删掉的点构成下一次bfs链表的点。(正难则反)。

bzoj 

bzoj 1018: [SHOI2008]堵塞的交通traffic

用线段树维护区间的四个端点的联通情况,然后查询的时候,把所有覆盖到的区间合并起来即可。

1178: [Apio2009]CONVENTION会议中心

求最多的不想交线段:去掉包含的情况(如果两条线段中的一条包含另一条,那么保留被包含的),然后左端点递增,右端点递增,就是贪心了,每个点往后找第一个不想交的就行,因为它是左端点,右端点最小的。

1106: [POI2007]立方体大作战tet

交换顺序不影响答案,先交换那个都行。所以树状数组维护,求两个点之间有多少个数,维护删除操作。

5462: [APIO2018] 新家

线段树套set,每个叶子结点维护一个set,在set里删除,求最小值。

两个堆维护求最小值+删除的操作,两个小根堆q1,q2,q1是所有的数,q2是删除的数,size=q1.size()-q2.size(),取最小值:出现在q1,不出现在q2中的最小值。

数颜色:离线扫一遍右端点,每次只记录最右边的点,然后查询左端点。

统计所有颜色是否全出现过:查询[l,r]区间,pre[i]为这个颜色的上一个位置,那么这也就说明了pre[i]+1这段区间没出现过,所以要求[r+1,n]这段区间的最小的pre都要大于等于l。

1912: [Apio2010]patrol 巡逻

两次bfs不能求带权直径

1130: [POI2008]POD Subdivision of Kingdom

复杂度为$C_n^m$的搜索。

O(n)预处理,O(1)查询$2^30$以内的数的二进制下1的个数。

4518: [Sdoi2016]征途

1、f数组double类型,然后就输出了,输出了这么一串1.30409e+007,最后输出时转化成int就好了,其实根本不需要double,为什么我开的double。。。

2、下面两个区别好大、上面是开始写的,下面是后来改的。return 1.0*(f[x]-f[y]+s[x]*s[x]-s[y]*s[y]) / 1.0*(s[x]-s[y]); return 1.0*(f[x]-f[y]+s[x]*s[x]-s[y]*s[y]) / (1.0*(s[x]-s[y]));

posted @ 2018-12-30 22:01  MJT12044  阅读(46)  评论(0编辑  收藏  举报