QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#584074 | #9245. Bracket Sequence | hos_lyric | ML | 0ms | 4080kb | C++14 | 7.3kb | 2024-09-23 07:40:52 | 2024-09-23 07:40:53 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")
////////////////////////////////////////////////////////////////////////////////
template <unsigned M_> struct ModInt {
static constexpr unsigned M = M_;
unsigned x;
constexpr ModInt() : x(0U) {}
constexpr ModInt(unsigned x_) : x(x_ % M) {}
constexpr ModInt(unsigned long long x_) : x(x_ % M) {}
constexpr ModInt(int x_) : x(((x_ %= static_cast<int>(M)) < 0) ? (x_ + static_cast<int>(M)) : x_) {}
constexpr ModInt(long long x_) : x(((x_ %= static_cast<long long>(M)) < 0) ? (x_ + static_cast<long long>(M)) : x_) {}
ModInt &operator+=(const ModInt &a) { x = ((x += a.x) >= M) ? (x - M) : x; return *this; }
ModInt &operator-=(const ModInt &a) { x = ((x -= a.x) >= M) ? (x + M) : x; return *this; }
ModInt &operator*=(const ModInt &a) { x = (static_cast<unsigned long long>(x) * a.x) % M; return *this; }
ModInt &operator/=(const ModInt &a) { return (*this *= a.inv()); }
ModInt pow(long long e) const {
if (e < 0) return inv().pow(-e);
ModInt a = *this, b = 1U; for (; e; e >>= 1) { if (e & 1) b *= a; a *= a; } return b;
}
ModInt inv() const {
unsigned a = M, b = x; int y = 0, z = 1;
for (; b; ) { const unsigned q = a / b; const unsigned c = a - q * b; a = b; b = c; const int w = y - static_cast<int>(q) * z; y = z; z = w; }
assert(a == 1U); return ModInt(y);
}
ModInt operator+() const { return *this; }
ModInt operator-() const { ModInt a; a.x = x ? (M - x) : 0U; return a; }
ModInt operator+(const ModInt &a) const { return (ModInt(*this) += a); }
ModInt operator-(const ModInt &a) const { return (ModInt(*this) -= a); }
ModInt operator*(const ModInt &a) const { return (ModInt(*this) *= a); }
ModInt operator/(const ModInt &a) const { return (ModInt(*this) /= a); }
template <class T> friend ModInt operator+(T a, const ModInt &b) { return (ModInt(a) += b); }
template <class T> friend ModInt operator-(T a, const ModInt &b) { return (ModInt(a) -= b); }
template <class T> friend ModInt operator*(T a, const ModInt &b) { return (ModInt(a) *= b); }
template <class T> friend ModInt operator/(T a, const ModInt &b) { return (ModInt(a) /= b); }
explicit operator bool() const { return x; }
bool operator==(const ModInt &a) const { return (x == a.x); }
bool operator!=(const ModInt &a) const { return (x != a.x); }
friend std::ostream &operator<<(std::ostream &os, const ModInt &a) { return os << a.x; }
};
////////////////////////////////////////////////////////////////////////////////
constexpr unsigned MO = 998244353;
using Mint = ModInt<MO>;
template <class T> struct DisjointSparseTable {
int logN, n;
vector<T> ts;
DisjointSparseTable() {}
template <class S> explicit DisjointSparseTable(const vector<S> &ss) {
n = ss.size();
for (logN = 1; 1 << logN < n; ++logN) {}
ts.resize(logN * n);
for (int i = 0; i < n; ++i) ts[i] = T(ss[i]);
for (int h = 1; h < logN; ++h) {
T *ths = ts.data() + h * n;
for (int i = 1 << h; i < n; i += 1 << (h + 1)) {
ths[i - 1] = ts[i - 1];
for (int j = i - 1; --j >= i - (1 << h); ) ths[j] = ths[j + 1].mulLeft(ss[j]);
ths[i] = ts[i];
for (int j = i + 1; j < i + (1 << h) && j < n; ++j) ths[j] = ths[j - 1].mulRight(ss[j]);
}
}
}
pair<T, T> getPair(int a, int b) const {
assert(0 <= a); assert(a <= b); assert(b <= n);
if (a == b) return std::make_pair(T(), T());
if (a + 1 == b) return std::make_pair(T(), ts[a]);
const int h = 31 - __builtin_clz(a ^ (b - 1));
return std::make_pair(ts[h * n + a], ts[h * n + (b - 1)]);
}
T get(int a, int b) const {
const auto res = getPair(a, b);
return res.first * res.second;
}
};
////////////////////////////////////////////////////////////////////////////////
int M;
/*
2.2.0(1)0(1)0.3.3
k: # open
*/
struct Node {
Mint a[4][4][21];
Node() : a{} {
for (int u = 0; u < 4; ++u) a[u][u][0] = 1;
}
Node(char c) {
*this = Node().mulRight(c);
}
Node mulLeft(char c) const {
Node t = *this;
for (int v = 0; v < 4; ++v) for (int k = 0; k <= M; ++k) t.a[0][v][k] += a[3][v][k];
for (int v = 0; v < 4; ++v) for (int k = 0; k <= M; ++k) t.a[2][v][k] += a[0][v][k];
if (c == '(') {
for (int v = 0; v < 4; ++v) for (int k = 0; k < M; ++k) t.a[0][v][k + 1] += a[1][v][k];
} else if (c == ')') {
for (int v = 0; v < 4; ++v) for (int k = 0; k <= M; ++k) t.a[1][v][k] += a[0][v][k];
} else {
assert(false);
}
return t;
}
Node mulRight(char c) const {
Node t = *this;
for (int u = 0; u < 4; ++u) for (int k = 0; k <= M; ++k) t.a[u][0][k] += a[u][2][k];
for (int u = 0; u < 4; ++u) for (int k = 0; k <= M; ++k) t.a[u][3][k] += a[u][0][k];
if (c == '(') {
for (int u = 0; u < 4; ++u) for (int k = 0; k < M; ++k) t.a[u][1][k + 1] += a[u][0][k];
} else if (c == ')') {
for (int u = 0; u < 4; ++u) for (int k = 0; k <= M; ++k) t.a[u][0][k] += a[u][1][k];
} else {
assert(false);
}
return t;
}
};
int N, Q;
char S[100'010];
vector<int> O, L, R, K;
int main() {
for (; ~scanf("%d%d", &N, &Q); ) {
scanf("%s", S);
O.resize(Q);
L.resize(Q);
R.resize(Q);
K.resize(Q);
for (int q = 0; q < Q; ++q) {
scanf("%d%d%d%d", &O[q], &L[q], &R[q], &K[q]);
--L[q];
}
M = *max_element(K.begin(), K.end());
const DisjointSparseTable<Node> dst(vector<char>(S, S + N));
for (int q = 0; q < Q; ++q) {
// cerr<<COLOR("33")<<O[q]<<" "<<L[q]<<" "<<R[q]<<" "<<K[q]<<COLOR()<<endl;
const auto res = dst.getPair(L[q], R[q]);
Mint ans = 0;
if (O[q] == 1) {
for (int w = 0; w < 2; ++w) for (int k = 0; k <= K[q]; ++k) {
ans += res.first.a[0][w][k] * res.second.a[w][0][K[q] - k];
}
} else if (O[q] == 2) {
for (const int u : {0, 2}) for (int w = 0; w < 4; ++w) for (const int v : {0, 3}) for (int k = 0; k <= K[q]; ++k) {
ans += res.first.a[u][w][k] * res.second.a[w][v][K[q] - k];
}
} else {
assert(false);
}
printf("%u\n", ans.x);
}
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 4080kb
input:
5 20 (()() 1 1 2 1 1 1 3 1 1 1 4 1 1 1 5 1 1 2 3 1 1 2 4 1 1 2 5 1 1 3 4 1 1 3 5 1 1 4 5 1 2 1 3 1 2 1 4 1 2 1 5 1 2 2 3 1 2 2 4 1 2 2 5 1 2 3 5 1 2 4 5 1 1 1 5 2 2 1 5 2
output:
0 2 2 5 1 1 3 0 1 1 3 6 16 1 2 7 2 1 2 3
result:
ok 20 lines
Test #2:
score: -100
Memory Limit Exceeded
input:
100000 1000000 )())))))())()()()(())))()())))()))))())))))()(()()))()()))((()()))()))((())(())())()(()))))()))(()()()()()(())(()((()))()((()(()))()))()))()()))(())))()()(()(()())())((()((()((())()(()()))())(())())())))))))((())(((()(())())))(()(((())())))(((((((((()))()())())(()))(())()()()()((()())...
output:
807252937 333653009 306141773 122104482 597950507 715981381 182568448 487609661 392529556 736028324 426329153 66499770 315566541 444655931 76394527 216715407 398566026 988659878 2314391 302716489 498728925 1522883 142406094 78253278 415123885 851121113 605305965 166689862 340780822 88059318 71955647...