QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#584071 | #9245. Bracket Sequence | hos_lyric | ML | 0ms | 3824kb | C++14 | 7.2kb | 2024-09-23 07:20:48 | 2024-09-23 07:20:49 |
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[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][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: 3824kb
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 312327855 196636735 122104482 597950507 273772659 736627400 509546752 392529556 736028324 426329153 378501382 315566541 444655931 76394527 216715407 90691078 450792938 919381468 302716489 498728925 1522883 427162255 78253278 299631184 44402603 605305965 147884184 340780822 7797800 92917844...