CF1223F Stack Exterminable Arrays 题解

前言:

CSP-S 2023 考寄了之后,过来补这题。

思路:

给一个似乎不一样的分治做法。考虑分治到当前这一层,我们扫一遍 $l \sim mid$ 的数,仿照括号匹配,依次放进栈中匹配。对于每个栈状态,考虑组成合法序列还要再加上什么,计算出相应的哈希值,放进 map 中。然后枚举 $mid + 1 \sim r$ 栈的状态,计算哈希值,在 map 中查询。复杂度 $O(n\log^2n)$。

#include<bits/stdc++.h>
using namespace std;
#define R(i, a, b) for(int i = a;i <= b;++i)
#define F(i, a, b) for(int i = a;i >= b;--i)
typedef long long ll;
const int N = 2e6 + 500;
const ll p1 = 318161;
const ll p2 = 233;
const ll M1 = 111111113;
const ll M2 = 5701123;
int T, n, top;
int a[N], st[N];
ll oc[N], ot[N], ans;
map<pair<ll, ll>, int>Q;
void solve(int l, int r) {
if(l >= r) return ;
int mid = l + r >> 1;
while(Q.size()) Q.erase(Q.begin());
top = 0;
F(i, mid, l) {
if(a[i] == a[st[top]]) top--;
else {
st[++top] = i;
oc[top] = (oc[top - 1] * p1 + a[i]) % M1;
ot[top] = (ot[top - 1] * p2 + a[i]) % M2;
}
Q[make_pair(oc[top], ot[top])]++;
}
top = 0;
R(i, mid + 1, r) {
if(a[i] == a[st[top]]) top--;
else {
st[++top] = i;
oc[top] = (oc[top - 1] * p1 + a[i]) % M1;
ot[top] = (ot[top - 1] * p2 + a[i]) % M2;
}
ans += Q[make_pair(oc[top], ot[top])];
}
solve(l, mid), solve(mid + 1, r);
}
void work() {
scanf("%d", &n);
R(i, 1, n) scanf("%d", &a[i]);
ans = 0, solve(1, n);
printf("%lld\n", ans);
}
int main(){
scanf("%d", &T);
while(T--) work();
return 0;
}

本文作者:Saka_Noa

本文链接:https://www.cnblogs.com/Saka-Noa/p/17808437.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Saka_Noa  阅读(12)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开