「考试」省选19

居然没出原题听奇怪。
好难啊。

T1
计算几何。
把x有交集的墙合并起来。
然后再每一个墙的端点上加入每一个$x$轴以上的点和这个端点的向量。
然后每个$vector$极角排序即可。
查询的时候对每个端点算出和当前点的向量,然后在$vector$中查询比这个点小的个数。
如果当前端点是左端点就+个数个,否则答案-个数个。
相当于一种差分,而会作出贡献的自然是那些被墙挡住的部分。也就是大于和起点的向量小于和终点的向量。

T2
线段树扫描线。
首先将查询的询问分成$[1,l-1]->[l,r]\(和\)[1,r]->[l,r]$这两个。
然后考虑如何维护这样的前缀信息。
扫描线。
设当前扫描位置为$l$,那么扫描线上位置$j$记录的信息就是$[1,l]->j$的所有信息。
然后我们需要的扫描线是可以得到如下一个函数:
\(ans_{L,R}=\sum\limits_{i=L}^{R}f_{r,i}(r)-\sum\limits_{i=L}^{R}f_{l-1,i}(l-1)\)
这个有点麻烦了。
因为需要代入一个$x$而算出众多贡献。
考虑如何做。
我们将$f$设为一个如下的函数:
\(f(x)=ax+b\)
然后首先初始化这个函数。
先直接算出$1->[1,n]$的所有$mex$,然后初始化$a_i=mex[i],b_i=0$。
这样初始的答案就是对的了。
然后考虑修改。
维护如下一个值$mx[x]$表示线段树区间中$mex[i]$的最大值。
然后我们发现$mex[x]$是递增的。
我们需要修改的是一段连续的区间。
设$nxt[i]$为$a[i]$在$i$之后下一次出现的位置。
也就是说当前位置从$l$移动到$l+1$的时候,对于所有的$i\in [l+1,nxt[l]-1]$,以这些位置为终点的所有$mex$值均要和$a[l]$取$min$。
因为这些部分$a[l]$并没有出现。
这样我们改变$mx[x]$的值。
同时也要改变$a,b$的值。
怎么做?
我们发现贡献对于后面代入的某个值是这样的。
如果某个位置将要被修改(\(mx[x]>a[l]\)
那么对于这个位置来说,$[1,l]$的所有起点对于当前这个右端点的贡献全部都减去$mx[x]-a[l]$,所以$b_x-=l*(mx[x]-a[l])$。
而同时,$[l+1,i]$也就是需要查询代入的值这一部分是不受影响的,所以$a_x+=mx[x]-a[l]$,这样直接用标记下传即可。
然后修改掉$mx[x]=d$即可。
查询的时候查询区间的$k$和以及$b$和,让他们一同做出贡献。
仍然有一个问题。
就是我们暴力的修改复杂度是无法保证的。
因此我们维护这样一个值$s[x]=0/1$,表示当前区间的所有点是否是同一个值,修改的时候如果是同一个值直接修改,否则向下递归。
然后一种颜色加入和被覆盖的复杂度都是$logn$,那么总的复杂度仍然是:\(O(nlogn)\)

T3
后缀排序。
考虑一种等价于最小表示法的方式。
如果当前位置为$i$,那么$a[i]$出现的上个位置为$j$,那么$j$的贡献即为$(i-j)*w^$,这样会得到一个$hash$值。
发现这种表示方法等价于最小表示法。
然后考虑后缀排序求出$height$数组,然后求出本质不同字串个数。
可以直接对后缀排序,然后比较的时候用二分+$hash$求$lcp$,如上给出了一种$hash$的求法
可以用主席树进行维护。
主席树每个位置代表以当前点为右端点,主席树上的位置为左端点的后缀的前缀的$hash$值。
然后根据上面我说的方式进行$hash$的更新。
可以发现相当于在给主席树的一段前缀区间加上一个等比数列,这里由于所有的等比数列公比相同,所以直接求首项和即可标记永久化来维护这一点。
然后可以求$hash$了,直接二分+$hash$求出$lcp$,然后比较下一个字符即可。
下一个字符可以用每种颜色的$vector$+$lower_bound$来求出。
然后就可以比较了。
比较的次数为$nlogn$次,每次比较的复杂度是$log2n$,所以总的复杂度是$O(nlog3n)$。
会被卡常,改成$stable_sort$,也就是归并排序(%%%湘源大神告诉我的)就可以过了。
另外$height$可以直接利用$lcp$来求。
这样就可以直接算出本质不同字串个数了。

posted @ 2020-02-06 19:30  Lrefrain  阅读(96)  评论(1编辑  收藏  举报