核心内容摘要
如何使用PowerTOP交互式模式:3分钟掌握Linux功耗实时监控
这道题难点在于状态设计。
考虑线性 DP设d p i dp_idpi为仅考虑前i ii个地雷且钦定第i ii个不引爆的方案数。
这样设计的好处在于i ii前面的地雷一定不会引爆i ii后面的从而满足无后效性。
注意需要在左右无穷远处各添加一个爆炸半径无穷大的哨兵地雷下标分别为0 00和n 1 n1n1确保哨兵能引爆所有地雷。
答案即为d p n 1 dp_{n1}dpn1。
然后考虑转移。
对于每个i ii枚举所有j i jiji然后判断引爆[ j 1 , i − 1 ] [j1,i-1][j1,i−1]中所有地雷是否会引爆i ii或j jj。
若均不会则能转移令d p i ← d p i d p j dp_i\leftarrow dp_idp_jdpi←dpidpj。
尝试转化这个条件。
设l i l_ili为i ii左边第一个会引爆i ii的地雷r i r_iri同理。
则上述条件等价于j ≥ l i j\ge l_ij≥li且i ≤ r j i\le r_ji≤rj。
l , r l,rl,r两个数组都可以单调栈上二分处理。
然后状态转移方程如下。
d p i ∑ j l i i − 1 [ i ≤ r j ] ⋅ d p j ∑ j 0 i − 1 [ i ≤ r j ] ⋅ d p j − ∑ j 0 l i − 1 [ i ≤ r j ] ⋅ d p j \begin{aligned} dp_i\sum_{jl_i}^{i-1}[i\le r_j]\cdot dp_j\\ \sum_{j0}^{i-1}[i\le r_j]\cdot dp_j-\sum_{j0}^{l_i-1}[i\le r_j]\cdot dp_j\\ \end{aligned}dpijli∑i−1[i≤rj]⋅dpjj0∑i−1[i≤rj]⋅dpj−j0∑li−1[i≤rj]⋅dpj先离线把d p i dp_idpi的两个询问分别挂在i − 1 i-1i−1和l i − 1 l_i-1li−1上然后树状数组扫一遍即可。
需要特殊处理j 0 j0j0的情况。
时间复杂度O ( n log n ) O(n\log n)O(nlogn)。
#includebits/stdc.h#definerept(i,a,b)for(inti(a);ib;i)#definepert(i,a,b)for(inti(a);ib;--i)#definelowbit(x)((x)-(x))#defineebemplace_back#defineintlonglongusingnamespacestd;constexprintN3e55,P1e97,INF3e18;structitem{intp,rad,lb,rb;}a[N];structquery{query()default;query(int_id,int_k):id(_id),k(_k){}intid,k;};intdp[N],st[N],l[N],r[N],s[N],n,top;vectorqueryq[N];voidadd(intp,intx){while(pn