首页 > 其他分享 >CF1830C Hyperregular Bracket Strings

CF1830C Hyperregular Bracket Strings

时间:2024-01-20 16:23:23浏览次数:39  
标签:ifac val int 括号 Bracket 区间 fac CF1830C Strings

Hyperregular Bracket Strings

Luogu CF1830C

题目描述

给定一个数 \(n\) 和 \(k\) 个区间 \(\left[l_i,r_i\right]\in [1,n]\)。

我们定义,对于一个长度为 \(n\) 的,仅由 () 组成的合法括号序列,如果它的每一个区间 \(\left[l_i,r_i\right]\) 内的子串都是合法括号序列,那么这个括号序列是好的

好的括号序列的数量,答案对 \(998244353\) 取模。

Solution

先考虑所有区间两两不交的情况。发现如果保证所有区间内的括号序列合法,那么对于所有不在区间内的位置组成的括号序列也会是合法的。比如 ()(()(())) 中 \([4,5]\) 是合法的,那么 \([1,3]\cup[6,10]\) 也是合法的。那么每个区间和剩余部分都是相互独立的。一个长度为 \(2m\) 的括号序列个数为卡特兰数 \(\displaystyle\binom{2m}{m}-\binom{2m}{m-1}\)。那么最后答案就是所有区间的括号序列个数的乘积。

但是此处区间可能存在交。只考虑两个相交的区间看有什么性质。发现两个区间 \([l,r],[a,b](r\ge a,l\le a)\),可以看作是三个不交的区间 \([l,a),[a,r),[r,b]\) 的组合。这样就把所有区间全部拆成不交的了。如果直接枚举相交的区间显然不行,考虑给每个区间随机一个权值 \(v\),然后将这个区间内的所有位置都异或上 \(v\),最后如果两个位置权值相同那么覆盖这两个位置的区间集合也是相同的。因此统计每个权值出现的次数然后用卡特兰数乘起来即可。

区间异或使用差分,时间复杂度 \(\mathcal O(n+k)\)。

Code
mint fac[_N], ifac[_N];
void init(int n) {
    fac[0] = 1; For(i, 1, n) fac[i] = fac[i-1] * i;
    ifac[n] = 1 / fac[n]; Rof(i, n, 1) ifac[i-1] = ifac[i] * i;
}
mint binom(int x, int y) {
    return x < y || y < 0 ? 0 : fac[x] * ifac[y] * ifac[x-y];
}
mint cat(int n) {
    if (n & 1) return 0;
    return binom(n, n / 2) - binom(n, n / 2 - 1);
}
mt19937_64 rnd(9);
signed main() {
    cin.tie(0)->sync_with_stdio(0);
    int T; cin >> T;
    init(3e5);
    while (T--) {
        int N, M; cin >> N >> M;
        vector<u64> val(N + 2, 0);
        For(i, 1, M) {
            int l, r; cin >> l >> r;
            u64 v = rnd();
            val[l] ^= v, val[r+1] ^= v;
        }
        unordered_map<u64, int> mp;
        For(i, 1, N) val[i] ^= val[i-1], ++mp[val[i]];
        mint ans = 1;
        for (auto& pr: mp) ans *= cat(pr.second);
        cout << ans << '\n';
    }
}

标签:ifac,val,int,括号,Bracket,区间,fac,CF1830C,Strings
From: https://www.cnblogs.com/hanx16msgr/p/17976655

相关文章

  • 无涯教程-MATLAB - 字符串(Strings)
    在MATLAB中创建字符串非常简单,实际上,我们已经使用了很多次。例如,您在命令提示符下键入以下内容-my_string='LearnfkPoint'MATLAB将执行上述语句并返回以下输出-my_string=LearnfkPointMATLAB将所有变量视为数组,而字符串则视为字符数组,让我们使用whos命令检查上面创建的变......
  • 无涯教程-Redis - Strings(字符串)
    Redis字符串命令用于管理Redis中的字符串值,以下是使用Redis字符串命令的语法。Strings-语法redis127.0.0.1:6379>COMMANDKEY_NAMEStrings-示例redis127.0.0.1:6379>SETlearnfkredisOKredis127.0.0.1:6379>GETlearnfk"redis"在上面的示例中,SET和GET......
  • [CF1902E] Collapsing Strings
    题目链接考虑拆贡献。显然答案可以拆成对于所有\(s_i\)的每一个后缀的反串,作为前缀在所有串中的出现次数的加和。这个东西字典树维护一下就行了。不知道是谁考场上写哈希赛后被人对着模数卡掉了点击查看代码#include<bits/stdc++.h>#defineFL(i,a,b)for(inti=(a......
  • CF1320D Reachable Strings
    110和011互相转化,相当于就是0在连续两个1的情况下,移动两个位置能够发现,0的位置的奇偶不会改变,且很多个0之间的相对位置不会改变猜想考虑这个答案只跟0的奇偶性有关,下面小证一下:(注意下面所说的“奇偶”指的是两个字符串的分别第一个字母为奇数时的奇偶,不是总字符串的奇偶)若0的......
  • [ARC141C] Bracket and Permutation
    考虑假设已知括号序列\(s\),如何求出\(p,q\)。对于求\(p\),考虑从\(s_1\)到\(s_n\)逐个往里放,如果能放就直接放,肯定不劣,否则就从后面抽最近的左括号放过来,然后继续放。不难证明不存在更优方案,对于\(q\)同理。接下来我们发现,如果\(p\)中存在\(p_i<p_{i-1}\),\(s_{p_{i......
  • 无涯教程-Erlang - Strings(字符串)
    通过将字符串括在引号中,可以在Erlang中构造一个字符串文字,需要使用双引号(如"HelloLearnfk")构造Erlang中的字符串。-module(helloLearnfk).-export([start/0]).start()->Str1="Thisisastring",io:fwrite("~p~n",[Str1]).上面程序的输出将是-“Thisisa......
  • Strings字符串
    字符串参考视频链接:【字符串】聪明办法学Python第二版_哔哩哔哩_bilibili用两种不同的引号是为了表达一些在引号里面要用到引号的情况!字符串中的转义字符前面有反斜杠\的字符,叫做转义字符(只能作为一个字符)print("双引号:\"")双引号:"print("反斜线:\\")反斜线:\print(......
  • 解决:Expected 1 line break before closing bracket, but no line breaks found.eslin
    运行时报错以下 解决在eslintrc.jsrules下添加以下代码'vue/singleline-html-element-content-newline':'off','vue/multiline-html-element-content-newline':'off', ......
  • Count Beautiful Substrings II
    CountBeautifulSubstringsIIYouaregivenastring s andapositiveinteger k.Let vowels and consonants bethenumberofvowelsandconsonantsinastring.Astringis beautiful if:vowels==consonants.(vowels*consonants)%k==0,inothert......
  • Go标准库学习:strings和bytes
    strings包和bytes包strings包和bytes包非常像,几乎所有函数都有string和[]byte两种接口,其中前者被实现在strings包中,而后者被是现在bytes包中,所以这里将这两个包一起学习。官方文档:strings包:https://pkg.go.dev/[email protected]包:https://pkg.go.dev/[email protected]函数......