「USACO 2021 US Open Platinum」United Cows of Farmer John
「USACO 2021 US Open Platinum」United Cows of Farmer John
考虑依次枚举右端点 \(i\) ,计算左边合法的方案数,设一个数 \(x\) 上次出现的位置为 \(lst_x\)
则 \(i\) 能够作为右端点的区间就是 \([lst_{a_i}+1,i-2]\)
考虑什么样的位置可以作为左端点,显然这个点在 \([1,i]\) 中是最后一次出现
我们将不妨这样的点权值设为 \(w_i=1\)
考虑一个点作为中间点贡献怎样的区间,同样的,这个点在 \([1,i]\) 中是最后一次出现
并且,能够贡献的区间 \(>\) 上一次出现的位置 \(lst_x\)
这个中间点能够匹配的左端点个数就是 \(\displaystyle \sum_{k=lst_{a_j}+1}^{j-1} w_k\)
现在我们要用数据结构动态修改某一个位置的 \(w_i\) ,增减 \([lst_{a_j}+1,j-1]\) 的区间,查询 \([lst_{a_i}+1,i-2]\)
不妨再为一个点增加点权 \(t_i\) ,此时我们要维护的操作
1.单点修改 \(w_i\)
2.区间修改 \(t_i\)
3.求 \(w_it_i\) 区间和
在线段树上每个节点维护 \(w_i\) 之和, \(w_it_i\) 之和,可以标记永久化 \(t_i\)
具体实现参考代码(实际写得很丑)
1 | const int N=2e5+10,INF=1e9+10; |