A.s1mple
直接做不好做,考虑求出答案数组经过某种变换后的数组,再经过逆变换求出答案数组。考虑求出答案的超集数组。
那么实际上就是钦定一些位置必须选1,其他位置任意的方案数。
假如钦定了一些位置是1,那么可以发现方案数只和每一个极长1连续段有关,于是可以暴力枚举每个极长连续1段的长度,总状态数为n的整数划分数。
给出的矩阵看成邻接矩阵,那么(b_{i,j}=1)等价于(i)到(j)有一条边。那么极长连续1段等价于可以将这个某个点集连成一条链。
假如已经确定了(f(S))表示将(S)内的点集连成一条链的方案数,并且枚举了一个n的划分,那么只要将这些(f(S))进行子集卷积,方案数就是(2^n-1)处的系数。由于集合的总长度恰好是n,所以这里的子集卷积得到的最后一项系数恰好就是对的。
于是可以得到答案的超集数组,然后进行(fwt)即可(O(1))询问。
B.s2mple
答案可以转化为给(S[l:r])加上一个前缀或者一个后缀的方案,两种方案不同当且仅当前缀不同或者后缀不同。
加上前缀可以考虑这个节点在(SAM)上的子树,那么只要求出子树每个节点能够加上的本质不同后缀数,这个东西可以在(SAM)上走转移边(dp)得到。
于是预处理一下每个节点的子树和就行了。
C.s3mple
首先把整个序列中的最大值提出来,然后可以划分成两个子问题,于是可以枚举左右的大小和总权值暴力(dp)。
然后将(dp)数组写成生成函数,发现转移实际上就是做卷积。然后可以用点值来做(dp)。
现在的问题是询问,要插值出这个多项式的某项系数,那么直接将拉格朗日插值的式子展开即可。
发现复杂度有点高,所以可以先求出所有多项式的积,求某一项的时候除掉一个多项式即可。