JOI2020题解
JOI2020题解
只不过是长的领带
显然最后一定是大的匹配大的,小的匹配小的。那么问题就是对于两个排好序的序列长度分别为\(N+1,N\)的\(A,B\)两个序列,求分别挖掉\(A\)中的每个位置的答案。这个东西可以通过维护前缀以及后缀的答案做到,复杂度\(O(n)\)。
JJOOII 2
只要确定一个满足有\(K\)级JOI-串的区间就可以确定一个可能答案。
那么我们可以枚举这个区间的起始位置\(i\),维护三个指针\(p1,p2,p3\)分别表示\([i,p1]\)中有\(K\)个J,\((p1,p2]\)中有\(K\)个O,\((p2,p3]\)中有\(K\)个I,那么\(i\)的贡献就是\(p3-i+1-3\times K\),所有\(i\)的贡献取个\(\min\)就好了,复杂度\(O(n)\)。
集邮比赛 3
考虑dp。因为时间较大,所以我们必须让状态里面不包括时间。
设\(f[i][j][k][0/1]\)表示目前走过\([1,i],[j,N]\),且目前收集了\(k\)张邮票,在\(i/j\)的最小时间,那么最终答案就是所有合法状态中最小的\(k\)。
奥运公交
因为反转一条边对从\(1\rightarrow n\)和从\(n\rightarrow 1\)的贡献其实是独立的,所以我们只需要考虑\(1\rightarrow n\)的贡献即可。
按照加删边最短路的套路,我们分别跑一遍正图上以\(1\)为起点的最短路求出\(dis1[i]\),一遍反图上以\(n\)为起点的最短路求出\(dis2[i]\),如果一条反转的边\((u,v)\)不在这两遍\(1\rightarrow n/n\rightarrow 1\)最短路中,那么可以直接通过比较\(dis1[v]+dis2[u]+c_{(u,v)}+d_{(u,v)}\)与原最短路的答案得出贡献。
如果\((u,v)\)在原最短路中,考虑这样的边数是\(O(n)\)级别的,我们可以重新跑最短路,此时使用不加堆优化的\(dijkstra\)可以做到单次\(O(n^2)\)。
火灾
以位置为\(x\)轴,时间为\(y\)轴建立坐标系,将询问拆为两个前缀相减,那么我们就是要求某个时间某一行的某个前缀和。
因为每次一个位置的变化都是一个\(a\rightarrow b\)的形式,而这样本质不同的\(a\rightarrow b\)实际上不超过\(n\)种,那么我们一次改变就是对平面某块区域加上\(b-a\)。
求出\(L_i=\max\{j|j<i,S_j>S_i\},R_i=\min\{j|j>i,S_j>S_i\}\),那么上述\(a\rightarrow b\)实际上就是\(S_i\rightarrow S_{L_i}\)。
考虑这种变化发生的时间与范围,那么可以知道,对于\(\forall j\in[i,R_i)\),上述过程会在\(j-L_i\)时刻发生,使\(p \in [i,R_i), t \ge p-L_i\)的\(S_p(t)\)加上\(S_{L_i}-S_i\)。
可以发现我们贡献的范围是个直角梯形,我们将这个直角梯形差分,令三元组\((x,y,w)\)表示经过\((x,y)\)且斜率为\(1\),从横坐标为\(x\)开始的上方区域全部加上\(w\),那么对于一个位置的贡献可表示为\((i,i-L_i,S_{L_i}-S_i),(R_i,R_i-L_i,S_i-S_{L_i})\)。
考虑一个修改\((x,y,w)\)对一个询问\((p,q)\)的贡献(\(p\geq x,q\geq y\))就是\(w\times \min\{p-x+1,q-y+1\}\),意味着一个点在\((x,y)\)上半部分和下半部分分别是算不同的两个贡献(\(-x+1\ \text{or}\ -y+1\) ),我们可以考虑将询问及修改离线,按照每个点的截距排序,那么每条直线的变化就可以通过扫描线很好的表示出来,然后可以分别算\(-x+1,-y+1\)两种类型的贡献。那么我们对于每种类型,维护一个\(\sum w\)以及一个\(\sum w\times i\)的树状数组即可维护(具体实现详见代码,我讲不清了)。