前言
我为什么会心血来潮,在noip来临前写这么一篇不务正业的文章呢?
其实大家知道,在比赛中,骗分是非巨佬选手的生命线,不会AK必然骗分,没有时间必然骗分,
可是有些骗分不仅比标准骗分好打,而且可以爆操标程(直接A掉),其中涉及到了一个很科学的学问,
下面举几个例子来非系统地总结一下这些神奇优化。
#1
玄学优化的核心,愚以为,是出题人在造数据时的随机性、恶毒性和思维局限性。
有一种题,如给你一个矩阵,n*m大小,q次询问,
每次对一个r*c的子矩阵求,而这个可以遍历一遍算出,
现在你发现,直接暴力过不了,
然后你可以推测,出题人出大数据的r,c肯定非常接近n,m,如下
这时不必慌,只需要反着求(总数减去红框以外部分)
最坏情况貌似是,但是考虑出题人恶毒,这种数据会极多,
于是,A之。
#2
有一种无上限01背包问题,给出的,显然暴力过不了,
虽然题目中有一些特殊限制使你可以想到正解,但是非巨佬,想不出,暴力+优化也
首先空间可以一维不说了,
于是你可以加一个优化,每一个数枚举的答案 j 上限限制在前缀和以内
for(int i=1,sum=w[1];i<=n;i++,sum+=w[i])
for(int j=sum;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
这样最坏情况貌似只能优化到,但是你可以先把数组按wi递增排序,那么可以最小化sum的总和,
考虑这种优化的优点,因为数据随机,所以wi不同的概率会很大,换言之,排序后,相邻两数w不同的概率很大,
于是总时间大概是以下图形的面积这种图形斜率是递增的,面积是很小的,如果数据足够随机的话。
遇懒出题人者,易A也。
#3
这其实是一种找小规律的优化,
以「雅礼集训 2017 Day5」珠宝为例(主要是我刚做),容易想到按300种w值分类,
然后就没有了,因为非巨佬,很难想后面的二分,所以只有在每一类中按价值v递减排序,
很容易地想到如果在相同w值的一类中,如果前面v值更大的点没有被选,那么此点肯定不用选了,
所以想想利用这个性质优化,记录前一个点做背包时成功计入贡献的下标,在这些下标处再dp,
for(int i=1;i<=300;i++){
for(r=0;r<=k-i;r++)d[r+1]=r;//初始化枚举的下标
for(int j=0;j<f[i].size();j++){
int o=0;
for(;r>0;r--){
if(d[r]+i<=k&&dp[d[r]]>=0&&dp[d[r]]+f[i][j]>dp[d[r]+i])
dp[d[r]+i]=dp[d[r]]+f[i][j],e[++o]=d[r]+i;
}
for(;o>0;o--)d[++r]=e[o];//更新下标数组
}
}
这种小优化,应该不可能过吧?
出题人:等等,我好像没有卡它的数据
然后我就过了
#4
有这样一道题:
一颗以 1 为根的树,一开始每个节点都是一颗棋子,一面白一面黑,白色的面朝上
接下来 q 次操作,操作分两种
0 操作 将一个颗棋子翻转
1 操作 询问一颗棋子与所有面朝上为黑色的棋子 lca 最深的那个的编号
这题一看,不推结论就是树剖,推结论就是一个线段树二分,
可是有位初二的选手,想到了基本做法(每个黑点往根更新一条链,查询从当前节点往上爬的第一个黑点),但是不会树剖,
于是他采用暴力更新,然后特判一条长链的情况,竟A。
为什么呢?因为除了长链的情况,其它的数据都不卡暴力(本质是数据水了)。
#5
暂时没有了,让我再翻翻以前的题~~