题目大意:
给定$n$个序列,要你从每个序列中选一个非空子串然后拼起来,拼成的序列的贡献为不同元素个数。
支持单点修改,在开始时和每次修改完后,输出所有不同选取方案的贡献和。
解题思路:
窝又来切Ynoi辣
STL题。
考虑每种元素的贡献,相当于求出有多少种方案包含这个数。补集转化成有多少种方案不包含这个数。
求有多少种方案不包含这个数,就相当于求每个序列有多少子区间不包含这个数,然后乘法原理。
而求有多少子区间不包含这个数,就相当于用这个数把序列分成若干区间,每个区间内部可以任意选取。
用一个数组存每种数有多少方案不包含,用map存每个序列里每种数有多少方案不包含,对每种数开个set存其位置。
插入的时候,相当于把一个大区间分裂成两个小区间,在set里查找前驱后继,更新map里的值即可。同时更新数组里的值和答案。删除的时候同理。
注意当一个序列只有一种数的时候,map里值为0,所以需要特殊处理一下,打个标记。
时间复杂度$O((n+m)\log n)$。
C++ Code:
#include #include #include #include #include