最近,小 R 新研制出了两种机器人,分别是 P 型机器人和 Q 型机器人。现在他要测试这两种机器人的移动能力,测试在从左到右排成一排的 n 个柱子上进行,柱子用 1−n 依次编号,i 号柱子的高度为一个正整数 hi。机器人只能在相邻柱子间移动,即:若机器人当前在 i 号柱子上,它只能尝试移动到 i−1 号和 i+1 号柱子上。
每次测试,小 R 会选取一个起点 s,并将两种机器人均放置在 s 号柱子上。随后它们会按自己的规则移动。
P 型机器人会一直向左移动,但它无法移动到比起点 s更高的柱子上。更具体地,P 型机器人在 l(l≤s) 号柱子停止移动,当且仅当下列两个条件均成立:
现在,小 R 可以设置每根柱子的高度,i 号柱子可选择的高度范围为 [Ai,Bi],即 Ai≤hi≤Bi。小 R 希望无论测试的起点 s 选在哪里,两种机器人移动过的柱子数量的差的绝对值都小于等于2。他想知道有多少种柱子高度的设置方案满足要求,小 R 认为两种方案不同当且仅当存在一个 k,使得两种方案中 k 号柱子的高度不同。请你告诉他满足要求的方案数模 109+7 后的结果。
int n, m, cnt; int l[kMaxN], r[kMaxN], unq[kMaxN * 2], id[kMaxN][kMaxN]; int f[kMaxM][kMaxN], g[kMaxM], fac[kMaxN], ifac[kMaxN], inv[kMaxN]; std::pair<int, int> seg[kMaxM]; std::vector<std::tuple<int, int, int>> nxt[kMaxM];
constexprintqpow(int bs, int64_t idx = kMod - 2){ int ret = 1; for (; idx; idx >>= 1, bs = (int64_t)bs * bs % kMod) if (idx & 1) ret = (int64_t)ret * bs % kMod; return ret; }
inlineintadd(int x, int y){ return (x + y >= kMod ? x + y - kMod : x + y); } inlineintsub(int x, int y){ return (x >= y ? x - y : x - y + kMod); } inlinevoidinc(int &x, int y){ (x += y) >= kMod ? x -= kMod : x; } inlinevoiddec(int &x, int y){ (x -= y) < 0 ? x += kMod : x; }
voiddfs(int l, int r){ staticbool vis[kMaxN][kMaxN]; if (l > r || vis[l][r]) return; seg[++cnt] = {l, r}, vis[l][r] = 1; for (int i = l; i <= r; ++i) { if (abs(i - l - (r - i)) <= 2) { dfs(l, i - 1), dfs(i + 1, r); } } }
voidgettrans(){ dfs(1, n); std::sort(seg + 1, seg + 1 + cnt, [&] (std::pair<int, int> &p1, std::pair<int, int> &p2) { return p1.second - p1.first > p2.second - p2.first; }); for (int i = 1; i <= cnt; ++i) id[seg[i].first][seg[i].second] = i; for (int i = 1; i <= cnt; ++i) { auto [l, r] = seg[i]; for (int j = l; j <= r; ++j) if (abs(j - l - (r - j)) <= 2) nxt[i].emplace_back(j, id[l][j - 1], id[j + 1][r]); } }