首页 > 其他分享 >Codeforces 1830C Hyperregular Bracket Strings

Codeforces 1830C Hyperregular Bracket Strings

时间:2024-02-29 11:36:02浏览次数:19  
标签:le int Codeforces long i64 Bracket 1830C inline mod

考虑到区间的限制 \([l, r]\) 就是要求 \([l, r]\) 里的字符会在 \([l, r]\) 里找到匹配。
假设还有个区间 \([l', r']\) 满足 \(l\le l'\le r\le r'\),能够发现限制变成了 \([l, l'), [l', r], (r, r']\) 这 \(3\) 个区间内的字符能在对应区间内找到匹配。
继续,假设 \(l\le l'\le r'\le r\),此时能发现是 \([l', r']\) 内的字符可以在这个区间里找到匹配,同时对于 \([l, l')\cup (r', r]\) 内的字符可以在这个集合中找到匹配。

于是可以想到用把覆盖其的区间相同的点划分到一个等价类中,一个等价类中的点就要求需要互相匹配。
对于互相匹配的方案数,设等价类中点个数为 \(p\),就相当于是求长度为 \(p\) 的合法括号序列的数量。
方案数就为 \(\operatorname{Catalan}(\frac{p}{2})\),当 \(p\bmod 2 = 1\) 时无解。

对于划分等价类,可以考虑 \(\text{xor-hash}\)。
具体来说,令点权为 \(a_i\),对于每个区间 \([l, r]\) 赋上一个权值 \(val\),就对 \(i\in [l, r]\) 进行 \(a_i\leftarrow a_i\oplus val\),这个是可以差分处理的。
正确性显然,不被相同的线段所覆盖的点肯定一个点相对于另一个点会多或者少 \(\oplus\) 一些线段的权值,权值就不会相同。
冲突的概率为 \(2^{-w}\) 次方的,采用 \(64\) 位碰撞的概率极小。

时间复杂度 \(O(n\log n)\)。

代码
#include<bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
const i64 mod = 998244353;
inline i64 qpow(i64 a, i64 b) {i64 v = 1; while (b) b & 1 && ((v *= a) %= mod), (a *= a) %= mod, b >>= 1; return v;}
const int maxn = 3e5 + 10, limn = 3e5;
i64 fac[maxn], invf[maxn];
inline i64 C(int n, int m) {return fac[n] * invf[m] % mod * invf[n - m] % mod;}
inline i64 Catalan(int n) {return n & 1 ? 0 : ((C(n, n / 2) - C(n, n / 2 - 1) + mod) % mod);}
inline void init() {
    fac[0] = 1;
    for (int i = 1; i <= limn; i++) fac[i] = fac[i - 1] * i % mod;
    invf[limn] = qpow(fac[limn], mod - 2);
    for (int i = limn; i; i--) invf[i - 1] = invf[i] * i % mod;
}
u64 val[maxn];
inline void Main() {
    std::mt19937_64 Rand(std::chrono::steady_clock::time_point().time_since_epoch().count());
    int n, k; scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i++) val[i] = 0;
    while (k--) {
        int l, r; scanf("%d%d", &l, &r);
        u64 v = Rand();
        val[l] ^= v, val[r + 1] ^= v;
    }
    for (int i = 1; i <= n; i++) val[i] ^= val[i - 1];
    std::sort(val + 1, val + n + 1);
    i64 ans = 1;
    for (int i = 1, j; i <= n; i = j) {
        for (j = i; j <= n && val[i] == val[j]; j++);
        (ans *= Catalan(j - i)) %= mod;
    }
    printf("%lld\n", ans);
}
int main() {
    init();
    int T; scanf("%d", &T);
    while (T--) Main();
    return 0;
}

标签:le,int,Codeforces,long,i64,Bracket,1830C,inline,mod
From: https://www.cnblogs.com/rizynvu/p/18043086

相关文章

  • Codeforces 863E Turn Off The TV
    能发现其实就是区间加查询区间最小值。如果最小值\(>1\)则这个区间可以删掉。考虑离散化端点,先把区间表示为\([l_i,r_i)\)的形式,方便离散化端点。这样子离散化出来的端点也是\([x,y)\)的形式。对于区间加查询区间最小值,很容易用线段树维护。时间复杂度\(O(n\logn)......
  • Codeforces Round 929 (Div. 3)
    CodeforcesRound929(Div.3)A-TurtlePuzzle:RearrangeandNegate代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingpii=pair<ll,ll>;#definefifirst#definesesecondusingi128=__int128_t;usingpiii=pa......
  • 13 Codeforces Round 886 (Div. 4)G. The Morning Star(简单容斥)
    G.TheMorningStar思路:用map记录x,y,以及y-x、y+x从前往后统计一遍答案即可公式\(ans+=cnt[x]+cnt[y]-2*cnt[x,y]+cnt[y+x]+cnt[y-x]\)\(cnt[x]+cny[y]-2*cnt[x,y]\)是统计坐标轴方向的,-2倍是需要把本身这个点给减去容斥是减一倍,这里还需要把自己给挖掉\(cnt[y+x]+cnt[y......
  • Codeforces 264E Roadside Trees
    首先考虑时间增长的问题,设第\(i\)棵树的种植时间为\(t_i\)。那么第\(x\)棵树比第\(y\)棵树高就是\(h_x+(t_y-t_x)>h_y\),也就是\(h_x-t_x>h_y-t_y\)。所以可以直接用\(h_i-t_i\)当作第\(i\)棵树的高度,即\(h'_i\leftarrowh_i-t_i\)。对于增加,考虑......
  • CodeForces 1844H Multiple of Three Cycles
    洛谷传送门CF传送门首先环是不用管的,只用判环长是否为\(3\)的倍数即可。考虑设\(f(x,y,z)\)表示\(x\)个\(1\)链,\(y\)个\(2\)链,\(z\)个\(0\)链,组成所有环长都为\(3\)的倍数的方案数。注意到\(f(x,y,z)=(x+y+z)f(x,y,z-1)\)(可以接到剩下的任意......
  • Codeforces Round 929 (Div. 3)
    B.TurtleMath:FastThreeTask数学#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=1e5+10;inta[N];voidsolve(){ intn; cin>>n; intsum=0; map<int,int>mp; intmx=0; for(inti=1;i<=n;i++){ cin......
  • 11 .Codeforces Round 891 (Div. 3)E. Power of Points(推公式+前缀和优化)
    E.PowerofPoints题解参考#include<bits/stdc++.h>#defineintlonglong#definerep(i,a,b)for(inti=(a);i<=(b);++i)#definefep(i,a,b)for(inti=(a);i>=(b);--i)#define_for(i,a,b)for(inti=(a);i<(b);++i)#definepii......
  • Codeforces Round 929 (Div. 3) 题解(D-G)
    比赛链接:https://codeforces.com/contest/1933官解暂未放出。质量不错的一场D3。CF1933D.TurtleTenacity:ContinualMods题意将数组\(a_{1..n}\ge1\)重排,问是否能使\(((a_1\mathbin{\rmmod}a_2)\mathbin{\rmmod}a_3)\cdots\mathbin{\rmmod}a_n\ne0\)......
  • Codeforces Round 929 (Div. 3)
    CodeforcesRound929(Div.3)比赛链接A.TurtlePuzzle:RearrangeandNegate思路根据题意,很明显数组中所有元素的绝对值总和就是答案Code#include<bits/stdc++.h>usingnamespacestd;#defineall(x)x.begin()+1,x.end()#defineintlonglongvoidsolve(){......
  • Codeforces 441E Valera and Number
    首先看到\(\times2\)\(+1\)和最后答案的计算方式,能想到看成二进制来处理。考虑到\(\times2\)就是在最后加了一个\(0\)。不妨倒过来看,\(\times2\)就相当于舍弃了最低位。于是可以考虑\(\text{DP}\),\(f_{i,j}\)为考虑后面的\(i\)个操作,目前\(+\)的值为\(j\)的......