CF1830C Hyperregular Bracket Strings
考虑包含与相交的区间。
对于相交的两区间 ,则只需区间 都合法即可。
对于相互包含的两区间 (前区间包含后区间),则只需区间 都合法即可。
考虑判断所有条件都满足后,区间的拆分情况。
发现对于相交的,即将 从两区间里拆分出来。
对于相互包含的,即将 从两区间里拆分出来。
于是考虑哈希判断。
对于条件 ,对 进行哈希将其分离出来即可。
对于最后的每个单独区间,我们只需要知道它的长度,开个桶统计即可。
长度为 的合法括号序列方案数为卡特兰数第 项。
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
typedef vector<int> vi;
#define F(i, a, b) for(int i = a; i <= (b); ++i)
#define F2(i, a, b) for(int i = a; i < (b); ++i)
#define dF(i, a, b) for(int i = a; i >= (b); --i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define Debug debug("Passing [%s] in LINS %d\n", __FUNCTION__, __LINE__)
#define pb push_back
#define fi first
#define se second
#define Mry debug("%.3lf MB\n", (&Mbe - &Med) / 1048576.0)
#define Try cerr << 1e3 * clock() / CLOCKS_PER_SEC << " ms\n";
typedef long long ll;
//namespace Fread {const int SIZE = 1 << 17; char buf[SIZE], *S, *T; inline char getchar() {if (S == T) {T = (S = buf) + fread(buf, 1, SIZE, stdin); if (S == T) return '\n';} return *S++;}}
//namespace Fwrite {const int SIZE = 1 << 17; char buf[SIZE], *S = buf, *T = buf + SIZE; inline void flush() {fwrite(buf, 1, S - buf, stdout), S = buf;} inline void putchar(char c) {*S++ = c;if (S == T) flush();} struct NTR {~NTR() {flush();}} ztr;}
//#ifdef ONLINE_JUDGE
//#define getchar Fread::getchar
//#define putchar Fwrite::putchar
//#endif
inline int ri() {
int x = 0;
bool t = 0;
char c = getchar();
while (c < '0' || c > '9') t |= c == '-', c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return t ? -x : x;
}
inline void wi(int x) {
if (x < 0) {
putchar('-'), x = -x;
}
if (x > 9) wi(x / 10);
putchar(x % 10 + 48);
}
inline void wi(int x, char s) {
wi(x), putchar(s);
}
bool Mbe;
const int mod = 998244353;
const int mod2 = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3f;
const int _ = 3e5 + 5;
int n, m, l[_], r[_], a[_], b[_], f[_];
map<pii, int> mp;
int qpow(int x, int y) {
int r = 1;
while(y) {
if(y & 1) r = 1ll * r * x % mod;
x = 1ll * x * x % mod, y >>= 1;
} return r;
}
void solve() {
mt19937 g(time(0) + rand());
n = ri(), m = ri();
F(i, 0, n + 2) a[i] = b[i] = 0; mp.clear();
F(i, 1, m) l[i] = ri(), r[i] = ri();
l[++m] = 1, r[m] = n;
F(i, 1, m) {
if((r[i] - l[i] + 1) & 1) {
puts("0"); return;
}
int x = g() % mod;
a[l[i]] = (a[l[i]] + x) % mod, a[r[i] + 1] = (a[r[i] + 1] + mod - x) % mod;
x = g() % mod2;
b[l[i]] = (b[l[i]] + x) % mod2, b[r[i] + 1] = (b[r[i] + 1] + mod2 - x) % mod2;
}
F(i, 1, n) {
a[i] = (a[i] + a[i - 1]) % mod;
b[i] = (b[i] + b[i - 1]) % mod2;
mp[make_pair(a[i], b[i])]++;
// cout << a[i] << ' ';
}
// cout << '\n';
// cout << f[2] << "@@\n";
int ans = 1;
for(auto v : mp) {
// cout << v.se <<"!!\n";
if(v.se & 1) {
puts("0"); return;
}
ans = 1ll * ans * f[v.se / 2] % mod;
} wi(ans, '\n');
}
bool Med;
signed main() {
srand(time(0));
// Mry;
f[0] = f[1] = 1;
F(i, 2, 300002) f[i] = 1ll * f[i - 1] * (4 * i - 2) % mod * qpow(i + 1, mod - 2) % mod;
int T = ri();
while(T--) solve();
// Try;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18121930