码迷,mamicode.com
首页 > 其他好文 > 详细

[题解+总结]20150810

时间:2015-08-11 22:56:57      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

1、前言

       今天是选拔考试第三天,所谓的省队难度,确实有点难,但是我们的发挥比实际难度还要差,暴力100分全场本年级的没有一个拿到,还有一大堆爆0的。好吧。cyb大神(@Delayyy)出的题,和他交流了一下,确实他看了成绩心情也是复杂的。三道题的话都是他国家集训队的作业题,CodeForces上面有英文原题,这下好了。这次考试不刻意作正解分析,更偏向于总结。

 

2、Tree 种树

大概题意:

       在一个数列中种树,每过一个月树长高1m。每个月初,你会收到两种要求之一:在位置p种一棵高度为h的树;砍掉当前第x棵树,且保证以后不会再种。每次操作之后求其最长上升子序列。

 

总结:

       这道题还是成功地把暴力打对了,直接模拟种树,砍树,用O(n log n)暴力求出最长上升子序列。考场上中间存在全部为种树操作的20分,但是n<=10^5,于是无聊写了个贪心自以为能够捞分,后来看了题解就打消了念头 = =。

 

题解(from Delayyy)

       把每棵树看做二维平面上的一个点(pos[i],h[i]),那么最长上升子序列等价于:每个点只能走到自己右上方的点,走的最长的链。

       定义f[i]表示从点i出发走的最长的链。我们发现,砍的树一定是最左边的10棵之一,种的树一定是最下的10棵之一。那么每次操作,我们删除对应的10个节点,然后按次序再逐个加入平面。每加入一个点,我们就要重新计算他的f值。

       由于加入时一定x或y有序,所以只要查询另一个坐标的前缀f最大值。于是我们对x轴、y轴分别开一棵线段树来维护f值,这样每次加入一个点时,用O(log w)可以查询并计算出他的f值,再用O(log w)就能更新线段树。(w表示坐标范围)

// 自己慢慢看吧。。。

 

3、Matrix 数字矩阵

大概题意:

有一个形如这样的数字矩阵:

1  2  5  10  17  26

4  3  6  11  18  27

9  8  7  12  19  28

16    15     14      13       20  29

25    24     23      22  21  30

36    35     34      33  32  31

有t组询问,每次给定x1,y1,x2,y2,你需要计算这个子矩阵之和的后10位,特别地,如果超过10位,需要在数字前加上“...”。

 

总结:

       这道题的暴力完全打错了。。。确实是太单纯了恩。注意,首先可以确定的是,对于某一个矩阵,要拆分成几个部分进行前缀矩阵的计算,但是在这个过程中,倘若你发现其数值大于10^10了就加上“...”,显然是不成立的,因为大于10^10的部分可能根本不在你所求矩阵之内(慢慢思考一下)。

       同样还有一个问题需要考虑,若取余之后的数值<=10^9,要在“...”之后补充若干个0。具体做法参见题解中的分析,总而言之的话,做题不要太过于想当然吧。

 

题解(from Delayyy):

       保留后10位等价于对10^10取模,然而这样是不够的,我们并不知道答案是否超过10位。解决方案是,再在mod 10^10+9的意义下做一次,可以大致认为答案不超过10^10当且仅当两次算出的答案一样。

       令f[x][y]=a[i][j](1<=i<=x,1<=j<=y),对于每一组询问,转化为:

                f[x2,y2]-f[x1-1][y2]-f[x2,y1-1]+f[x1-1][y1-1]。

       首先我们可以发现,对于f[x][y],当x=y时,可以直接O(1)算出(等差数列和公式)。然后,当x!=y时,就存在一部分不属于直接计算部分,对面多出来的x行,每一行都是连续的若干数字(列也是同理),求出第一行的和S[1],给答案加上x*S[1],这样每一行剩下没计算的值形如:

1   1

2   2*t+2

3   3*t+2+4

4   4*t+2+4+6

求和起来为:t*i+2*i*(x-i-1) (1<=i<=x)

       这个式子拆开就是一些i(1<=i<=n)和 i^2(1<=i<=n)和一些常数,都是可以O(1)求的。好吧由于mod有点大,要用O(log)的大数乘法,但是其实有一种O(1)的写法,省略。

 

4、Happy 愉悦

大概题意:

       有一个数列a[1..n],每次你可以删除a[l..r],满足:|a[i]-a[i+1]|=1 (l<=i<r);2a[i]-a[i+1]-a[i-1]>=0(l<i<r)。删除长为x的连续一段可以获得val[x]的收益,求最大收益。

 

总结:

      大概题意里没有提到,其实原题里面有一句很重要的话——每次删除之后两端的序列会重新连接起来!!!考试的时候看到了,但是由于最后时间比较紧,所以导致写DFS的时候没有去接啊。。。结果捧着个10分回来了。以后要多加注意细节啊。

[题解+总结]20150810

标签:

原文地址:http://www.cnblogs.com/jinkun113/p/4722345.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!