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;
}
posted @ 2023-10-23 10:07  Saka_Noa  阅读(18)  评论(0)    收藏  举报  来源