D - Cutting Woods

记录每一个切割点,每次求前驱后驱就好了,注意简单判断一下开闭区间。

考场上采用的 FHQ_Treap 无脑莽。

#include <cstdio>
#include <cstdlib>
using namespace std; typedef long long LL;
LL Max(LL x, LL y) { return x > y ? x : y; }
LL Min(LL x, LL y) { return x < y ? x : y; }
LL Abs(LL x) { return x < 0 ? -x : x; } int read() {
int k = 1, x = 0;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * k;
} LL read_LL() {
int k = 1;
LL x = 0;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * k;
} void write(LL x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
} void print(LL x, char s) {
write(x);
putchar(s);
} // Fhq-Treap
const int MAXN = 2e5 + 5; struct Fhq_Treap {
struct Fhq_Node {
int l, r, val, key, size;
#define lson tr[p].l
#define rson tr[p].r
Fhq_Node() {}
Fhq_Node(int L, int R, int Val, int Key, int Size) {
l = L;
r = R;
val = Val;
key = Key;
size = Size;
}
} tr[MAXN];
int tot, root; Fhq_Treap() {
tot = 0, root = 0;
} int Get(int val) {
tr[++tot] = Fhq_Node(0, 0, val, rand(), 1);
return tot;
} void Push_Up(int p) { tr[p].size = tr[lson].size + tr[rson].size + 1; } void Split(int p, int val, int &x, int &y) {
if (!p) {
x = 0, y = 0;
return;
}
if (tr[p].val <= val) {
x = p;
Split(rson, val, rson, y);
} else {
y = p;
Split(lson, val, x, lson);
}
Push_Up(p);
} int Merge(int x, int y) {
if (!x || !y)
return x + y;
if (tr[x].key <= tr[y].key) {
tr[x].r = Merge(tr[x].r, y);
Push_Up(x);
return x;
} else {
tr[y].l = Merge(x, tr[y].l);
Push_Up(y);
return y;
}
} void Insert(int val) {
int x, y;
Split(root, val, x, y);
root = Merge(Merge(x, Get(val)), y);
} void Delete(int val) {
int x, y, z;
Split(root, val, x, z);
Split(x, val - 1, x, y);
y = Merge(tr[y].l, tr[y].r);
root = Merge(Merge(x, y), z);
} int Get_Rank(int val) {
int x, y, ret;
Split(root, val - 1, x, y);
ret = tr[x].size + 1;
root = Merge(x, y);
return ret;
} int Get_Val(int Rank) {
int p = root;
while (p) {
if (tr[lson].size + 1 == Rank)
return tr[p].val;
else if (Rank <= tr[lson].size)
p = lson;
else {
Rank -= (tr[lson].size + 1);
p = rson;
}
}
return 0;
} int Get_Pre(int val) {
int x, y, p;
Split(root, val - 1, x, y);
p = x;
while (rson) p = rson;
int ret = tr[p].val;
root = Merge(x, y);
return ret;
} int Get_Next(int val) {
int x, y, p;
Split(root, val, x, y);
p = y;
while (lson) p = lson;
int ret = tr[p].val;
root = Merge(x, y);
return ret;
}
#undef lson
#undef rson
} tree; int main() {
int l = read(), q = read();
tree.Insert(0);
tree.Insert(l);
for(int i = 1, opt, x; i <= q; i++) {
opt = read(), x = read();
if(opt == 1)
tree.Insert(x);
else
print(tree.Get_Next(x) - tree.Get_Pre(x), '\n');
}
return 0;
}

E - Sorting Queries

将所有的插入操作先存进一个临时序列。

在遇到排序操作时再处理这些序列里的元素。

具体来说就是直接丢进优先队列。也可以学我赛时直接 copy D 的 code 来改。

#include <queue>
#include <cstdio>
using namespace std; typedef long long LL;
LL Max(LL x, LL y) { return x > y ? x : y; }
LL Min(LL x, LL y) { return x < y ? x : y; }
LL Abs(LL x) { return x < 0 ? -x : x; } int read() {
int k = 1, x = 0;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * k;
} LL read_LL() {
int k = 1;
LL x = 0;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * k;
} void write(LL x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
} void print(LL x, char s) {
write(x);
putchar(s);
} const int MAXN = 2e5 + 5; int num[MAXN], len = 0, tot = 1;
priority_queue<int, vector<int>, greater<int> > q; int main() {
int n = read();
for(int i = 1, opt; i <= n; i++) {
opt = read();
if(opt == 1) {
int x = read();
num[++len] = x;
}
else if(opt == 2) {
if(!q.empty()) {
print(q.top(), '\n');
q.pop();
}
else {
print(num[tot], '\n');
tot++;
}
}
else {
for(int i = tot; i <= len; i++)
q.push(num[i]);
tot = 1, len = 0;
}
}
return 0;
}

F - Make Pair

小清新的区间 dp 题。

相邻删除这样的操作就应该往区间 dp 上去想。

定义 \(f(i, j)\) 表示将区间 \([i, j]\) 匹配完的方案数,显然需要满足 \(2 \mid r - l + 1\)。

可得:

\[f(i, j) = \sum_{k \in (l, r], 2 | k - i + 1} f(i + 1, k) \times f(k + 1, j) \times \binom{\frac {j - i + 1} {2}}{\frac {j - k + 1} {2}}
\]

其中 \(k\) 同学和 \(i\) 同学关系友好,且对于任意 \(i\),若 \(0 \leq i \leq n\),有 \(f(i, i + 1) = 1\)。

其中组合数可以理解为我们共有 \(\frac {j - i + 1} {2}\) 个盒子(盒子间被认为是不同的),且我们有 \(\frac {k - i - 1} {2}\) 个 \(a\) 球,\(1\) 个 \(b\) 球,和 \(\frac {j - k} {2}\) 个 \(c\) 球(同种类的球被认为是相同的,这是因为在上面的转移柿子中我们已经考虑了球种类内部的情况),且 \(b\) 球放入的盒子编号必须大于任意一个 \(a\) 球放入的盒子编号。

感性理解一下其实就是我们在所有的盒子中选 \(\frac {j - k} {2}\) 个出来放 \(c\) 球。

时间复杂度 \(O(n^3)\)。

#include <cstdio>

typedef long long LL;
int Max(int x, int y) { return x > y ? x : y; }
int Min(int x, int y) { return x < y ? x : y; }
int Abs(int x) { return x < 0 ? -x : x; } int read() {
int x = 0, k = 1;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while ('0' <= s && s <= '9') {
x = (x << 3) + (x << 1) + (s - '0');
s = getchar();
}
return x * k;
} void write(LL x) {
if (x < 0) {
x = -x;
putchar('-');
}
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
} void print(LL x, char s) {
write(x);
putchar(s);
} const int MAXN = 4e2 + 5;
const int mod = 998244353; bool w[MAXN][MAXN];
LL q[MAXN], sq[MAXN], dp[MAXN][MAXN]; LL A (int x, int y) { return q[x] * sq[x - y] % mod;} LL C (int x, int y) { return A(x, y) * sq[y] % mod;} LL Quick_Pow(LL a, LL b) {
LL res = 1;
while(b) {
if(b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res % mod;
} int main() {
int n = read(), m = read();
q[0] = 1, sq[0] = 1;
for(int i = 1; i <= (n << 1); i++) {
q[i] = q[i - 1] * i % mod;
sq[i] = Quick_Pow(q[i], mod - 2);
}
for(int i = 1, a, b; i <= m; i++) {
a = read(), b = read();
w[a][b] = w[b][a] = true;
}
for(int i = 1; i <= (n << 1) + 1; i++)
dp[i][i - 1] = 1;
for(int len = 2; len <= (n << 1); len += 2)
for(int l = 1; l + len - 1 <= (n << 1); l++) {
int r = l + len - 1;
for(int k = l + 1; k <= r; k += 2)
if(w[l][k])
dp[l][r] = (dp[l][r] + dp[l + 1][k - 1] * dp[k + 1][r] % mod * C(len / 2, (r - k + 1) / 2) % mod) % mod;
}
print(dp[1][n << 1], '\n');
return 0;
}

G - Groups

还是一道 dp 呢。

我们定义 \(f(i, j)\) 表示分完前 \(i\) 个数且当前分了 \(j\) 个组。

考虑当前数的两种决策。

第一种,新开一个组,即方案数为 \(f(i - 1, j - 1)\)。

第二种,不开新的组而是丢进已存在的组,不难发现当前数可以丢入的组共有 \(j - t(i, i \bmod m)\) 个,其中 \(t(x, y) = \sum_{i = 1}^{x} [i \bmod m = y]\)。

故可得,\(f(i, j) = f(i - 1, j - 1) + f(i - 1, j) \times (j - t(i, i \bmod m))\)。

初始状态为 \(f(0, 0) = 1\)。其他的比如 \(t(x, y)\) 的转移啦、答案状态啦就很简单了嘛,时间复杂度 \(O(n^2)\)。

#include <cstdio>

typedef long long LL;
LL Max(LL x, LL y) { return x > y ? x : y; }
LL Min(LL x, LL y) { return x < y ? x : y; }
LL Abs(LL x) { return x < 0 ? -x : x; } int read() {
int k = 1, x = 0;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * k;
} LL read_LL() {
int k = 1;
LL x = 0;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * k;
} void write(LL x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
} void print(LL x, char s) {
write(x);
putchar(s);
} const int MAXN = 5e3 + 5;
const int mod = 998244353; int t[MAXN];
LL dp[MAXN][MAXN]; int main() {
int n = read(), m = read();
dp[0][0] = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++)
dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j] * ((j - t[i % m] + mod) % mod) % mod) % mod;
t[i % m]++;
}
for(int i = 1; i <= n; i++)
print(dp[n][i], '\n');
return 0;
}

H - Snuketoon

不会了不会了不会了 /fad。

Solution -「ABC 217」题解的更多相关文章

  1. Solution Set -「ABC 217」

      大家好屑兔子又来啦! [A - Lexicographic Order]   说个笑话,\(\color{black}{\text{W}}\color{red}{\text{alkingDead} ...

  2. Solution -「ABC 219H」Candles

    \(\mathcal{Description}\)   Link.   有 \(n\) 支蜡烛,第 \(i\) 支的坐标为 \(x_i\),初始长度为 \(a_i\),每单位时间燃烧变短 \(1\) ...

  3. Solution -「ABC 215H」Cabbage Master

    \(\mathcal{Description}\)   Link.   有 \(n\) 种颜色的,第 \(i\) 种有 \(a_i\) 个,任意两球互不相同.还有 \(m\) 个盒子,每个盒子可以被放 ...

  4. Solution -「ABC 213G」Connectivity 2

    \(\mathcal{Description}\)   Link.   给定简单无向图 \(G=(V,E)\),点的编号从 \(1\) 到 \(|V|=n\).对于 \(k=2..n\),求 \(H= ...

  5. Solution -「ABC 213H」Stroll

    \(\mathcal{Description}\)   Link.   给定一个含 \(n\) 个结点 \(m\) 条边的简单无向图,每条边的边权是一个常数项为 \(0\) 的 \(T\) 次多项式, ...

  6. Solution -「ARC 104E」Random LIS

    \(\mathcal{Description}\)   Link.   给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...

  7. Solution -「ARC 110E」Shorten ABC

    \(\mathcal{Description}\)   Link.   给定长度为 \(n\),包含 A, B, C 三种字符的字符串 \(S\),定义一次操作为将其中相邻两个不相同的字符替换为字符集 ...

  8. Solution -「CTS 2019」「洛谷 P5404」氪金手游

    \(\mathcal{Description}\)   Link.   有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...

  9. Solution -「BZOJ 3812」主旋律

    \(\mathcal{Description}\)   Link.   给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...

随机推荐

  1. WIN10 使用POWERSHELL 设置单应用KIOSK模式(win10家庭版或企业版)

    win10 使用PowerShell 设置单应用kiosk模式 win10 家版或企业版PowerShellshell 启动器 v1Autologon.exe 注意事项 win10 家庭版或企业版. ...

  2. Golang 实现 Redis(10): 本地原子性事务

    为了支持多个命令的原子性执行 Redis 提供了事务机制. Redis 官方文档中称事务带有以下两个重要的保证: 事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中 ...

  3. python使用虚拟环境venv

    venv模块支持使用自己的站点目录创建轻量级"虚拟环境",可选择与系统站点目录隔离.每个虚拟环境都有自己的Python二进制文件(与用于创建此环境的二进制文件的版本相匹配),并且可 ...

  4. Spring Framework 远程命令执行漏洞(CVE-2022-22965)

    Spring Framework 远程命令执行漏洞 (CVE-2022-22965) 近日,Spring 官方 GitHub issue中提到了关于 Spring Core 的远程命令执行漏洞,该漏洞 ...

  5. ElasticSearch7.3学习(二十四)----相关度评分机制详解

    1.算法介绍 relevance score(相关性分数) 算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度.Elasticsearch使用的是 term freque ...

  6. nslookup:command not found的解决办法

    nslookup:command not found的解决办法 通过nslookup查看DNS记录,在这里遇到了一个小插曲,nslookup:command not found(未找到命令),是因为新 ...

  7. 【系统问题】windows10打印就蓝屏-报错误代码“win32kfull.sys”

    现象描述: 打印机一打印电脑就蓝屏,蓝屏错误代码为:win32kfull.sys 原因分析: 2021年3月9日-推送了KB5000802补丁更新(操作系统内部版本19041.867和19042.86 ...

  8. 基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转

    在前面随笔,我们介绍过这个基于SqlSugar的开发框架,我们区分Interface.Modal.Service三个目录来放置不同的内容,其中Modal是SqlSugar的映射实体,Interface ...

  9. MTK 虚拟 sensor bring up (pick up) sensor1.0

    pick up bring up sensor1.0 1.pick up对比 2.SCP 1.添加驱动文件 2.添加编译环境(打开开关) 注:编译过程中如果显示内存不够 3.修改底层数据上报方式 3. ...

  10. JavaScript Number -> String

    六种将Number类型转化为String类型的方法: 方法一:通过+运算符加上一个空字符串: eg:'' + 5 -> '5'      5 + '' -> '5' 方法二:toStrin ...