模拟87 题解
A. maze
做过类似的题,维护最短路对于$k$的一个凸包,答案就是凸包与$y=s$直线交点的横坐标,这个还挺难打的。
然而答案显然具有单调性,所以直接二分答案就完了。
实际上,这个二分答案的操作,等价于选定直线$x=mid$,
求出$x=mid$与凸包的交点的纵坐标,并通过这个纵坐标与$s$比较来确定最终的$mid$即答案。
B. bird
将鸟的移动转化为人的移动,则问题是相邻$k$个位置最多打一枪。
设$dp_i$表示最后一枪在$i$处打的最优答案。
那么有转移$dp_i=dp_j+cnt_{j,i}$,$cnt_{j,i}$表示$j$处打不到但$i$处能打到的鸟的个数。
这个东西并不难维护,
对于每一个鸟,我们只要
在$l_i$处给$dp_0$~$dp_{l-1}$加上1,
在$r_{i+1}$处给$dp_0$~$dp_{l-1}$减去1,
用线段树进行加减操作,维护最值就完了。
C. stone
设$f(i,j)$表示点对$(i,j)$是否合法,只有$0/1$两个取值。
有转移
$a[i]=b[j]$ $f[i+1][j+1]=f[i][j]$
$a[i]!=b[j]$ $f[i+1][j]=f[i][j],f[i][j+1]=f[i][j]$
显然对于同一个$i$,$f(i,j)$取值为$1$的区间大概是连续的,设左右端点分别为$l_i$,$r_i$。
$l$,$r$数组的求法都是简单的。
然而$l_i,r_i$范围内并不全为$1$,其中穿插着许多$0$。
总的答案是$l_i$,$r_i$范围减去其中$0$的个数。
不妨先打出表来,实际上,打出的表告诉我们,结论是:答案要减去的是$b$字符串$l_i$,$r_i$范围内,
与字符串$s=a[i-1],a[i]$逆序的子串个数,即$l_i<=j<=r_i$ $a[i]==b[j-1],a[i-1]==b[j],a[i]!=a[i+1]$的个数。
一句话,答案为:$ans=\sum \limits_{i=1}^{n}r_i-l_i+1-\sum \limits_{j=l_i}^{r_i}[a[i]==b[j-1],a[i-1]==b[j],a[i]!=a[i-1]]$
由于$l$,$r$数组都是单调不降的,加上字符集只有$A,B,C$。
可以直接用单调指针求出后一个求和式,当然前缀和也是可以的。
考虑表中的$0$意味着什么。
因为$a[i-1]!=b[j-1]$ $a[i-1]==b[j]$ $a[i]==b[j-1]$等价于$a$,$b$形成逆序串。
我们用逆序串的个数求出了$f$值等于$0$的点对数,所以要证明的是:(注意下面的$f[i][j]$保证$j$在$l_i,r_i$范围内)
$f[i][j]=0$的充要条件是
1.$a[i-1]!=b[j-1]$
2.$a[i-1]==b[j]$
3.$a[i]==b[j-1]$
因为$f[i][j]$没有被$f[i-1][j-1]$转移,那么$f[i-1][j-1]==0$或$a[i-1]!=b[j-1]$。
因为$f[i][j]$没有被$f[i-1][j]$转移,那么$f[i-1][j]==0$或$a[i-1]==b[j]$
因为$f[i][j]$没有被$f[i][j-1]$转移,那么$f[i][j-1]==0$或$a[i]==b[j-1]$
因为有三个或,其充分性是显然的。
下面证$f[i-1][j]=1$和$f[i][j-1]=1$,即条件2 3是必要的:
1.假设$f[i-1][j-1]=1$,那么由$f[i][j]=0$,
$f[i-1][j-1]$必定要转移到$f[i-1][j]$和$f[i][j-1]$,所以$f[i-1][j]=f[i][j-1]=1$。
2.假设$f[i-1][j-1]=0$,由上述的证明,我们可以归纳得知$f[i-1][j-2]=1$,
由于$f[i-1][j-1]=0$,那么$f[i-1][j-2]$必定要转移到$f[i][j-1]$,所以$f[i][j-1]=1$,同理可得$f[i-1][j]=1$。
证毕。
下面证条件1是必要的:
1.假设$f[i-1][j-1]=1$,那么显然是必要的。
2.假设$f[i-1][j-1]=0$,那么在$(i-1,j-1)$,字符串$a$,$b$已经形成了逆序串,那么显然$a[i-1]!=b[j-1]$。
所以上述三个条件是充要的,$(i,j)$存在逆序串等价于$f[i][j]=0$,所以我们的计算是合理的。