2019暑期集训 - Day 18
没什么,就是惨就对了
概述
提高 B 组
3题:T0 , T1 , T2
10/300 分
121/134 名
T0 能量获取
WA 0/100 分
Description
“封印大典启动,请出 Nescafe 魂珠!”随着圣主 applepi 一声令下,圣剑护法 rainbow 和魔杖护法 freda 将 Nescafe 魂珠放置于封印台上。封印台是一个树形的结构,魂珠放置的位置就是根节点(编号为 \(0\) )。还有 \(n\) 个其他节点(编号 \(1\sim n\) )上放置着封印石,编号为 \(i\) 的封印石需要从魂珠上获取 \(E_i\) 的能量。能量只能沿着树边从魂珠传向封印石,每条边有一个能够传递的能量上限 \(W_i\) ,魂珠的能量是无穷大的。作为封印开始前的准备工作,请你求出最多能满足多少颗封印台的能量需求?
注意:能量可以经过一个节点,不满足它的需求而传向下一个节点。每条边仅能传递一次能量。
Input
第一行一个整数 \(n\) ,表示除根节点之外的其他节点的数量。
接下来 \(n\) 行,第 \(i+1\) 行有三个整数 \(F_i\) 、 \(E_i\) 、 \(W_i\) ,分别表示 \(i\) 号节点的父节点、 \(i\) 号节点上封印石的能量需求、连接节点 \(i\) 与 \(F_i\) 的边最多能传递多少能量。
Output
最多能满足多少颗封印石的能量需求。
Sample Input
4
0 3 2
0 100 100
1 1 1
2 75 80
Sample Output
2
Hint
对于100% 的数据,满足\(1\le n\le 1000\ ,\ 0\le F_i\le n\ ,\ 0\le E_i,W_i\le 100\)
Solution
贪心???
确实是贪心。
每次尝试满足能量需求最小的封印石。
就是这样的。
瞎写一下就能过了。
T1 封印一击
WA 10/100 分
Description
“圣主 applepi 于公元 2011 年 9 月创造了 Nescafe ,它在散发了 16 次光辉之后与公元 2011 年 11 月 12 日被封印为一颗魂珠,贮藏于 Nescafe 神塔之中。公元 2012 年 9 月,圣主带领四大护法重启了 Nescafe ,如今已经是 Nescafe 之魂的第 30 次传播了。不久,它就要被第二次封印,而变成一座神杯。。。” applepi 思索着 Nescafe 的历史,准备着第二次封印。
Nescafe 由 \(n\) 种元素组成(编号为 \(1\sim n\) ),第 \(i\) 种元素有一个封印区 \([a_i,b_i]\) 。当封印力度 \(E\) 小于 \(a_i\) 时,该元素获得 \(a_i\) 的封印能量;当封印力度 \(E\) 在 \(a_i\) 到 \(b_i\) 之间时,该元素将获得 \(E\) 的封印能量;而当封印力度 \(E\) 大于 \(b_i\) 时,该元素将被破坏从而不能获得任何封印能量。现在圣主 applepi 想选择恰当的 \(E\) ,使得封印获得的总能量尽可能高。为了封印的最后一击尽量完美,就请你写个程序帮他计算一下吧!
Input
第一行一个整数 \(N\) 。
接下来 \(N\) 行每行两个整数 \(a_i\) 、 \(b_i\) ,第 \(i+1\) 行表示第 \(i\) 种元素的封印区间。
Output
两个用空格隔开的证书,第一个数十能够获得最多总能量的封印力度 \(E\) ,第二个数是获得的总能量大小。当存在多个E能够获得最多总能量时,输出最小的E。
Sample Input
2
5 10
20 25
Sample Output
10 30
Hint
对于50% 的数据, \(1\le N\le 1000\ ,\ 1\le a_i\le b_i\le 10000\) 。
对于100% 的数据,\(1\le N\le 10^5\ ,\ 1\le a_i\le b_i\le 10^9\)。
Solution
感觉好暴力啊
\(E\) 肯定与一个 \(a_i\) 或 \(b_i\) 相等(否则总能让它加或减一个数得到更优的解)。
从小到大合在一起 sort 一遍 \(a_i,b_i\) ,然后从左往右一个一个扫描。
维护一个变量 \(sa\) ,表示扫描到的值为 \(p\) 时,左端点大于 \(p\) 的所有区间的左端点之和;维护一个变量 \(sp\) ,表示扫描到的值为 \(p\) 时, \(p\) 在左右端点之间的区间个数。那么此时可以封印一击得到的能量就是 \(sa+sp\times p\)。
扫描时遇到一个左端点, \(sa\) 减去这个左端点, \(sp\) 加一;遇到一个右端点, \(sp\) 减一即可。
T2 归途与旅程
WA 0/100 分
Description
“感谢你们来访 Nescafe 之塔,封印的能量会在两天之内完全被贮存在神杯之中,你们也该回去了。”
“不过圣主,我们还有一个问题。难道…… Nescafe 就这样被封印成一座神杯,保存在塔中了吗?”
“也许吧。谁知道呢?或许来年的秋天会有有识之士来开启它呢……”
“有识之士?他是谁?”
“如果有这样几个人,那他们一定来自忘川沧月家族的 10 个孩子!他们……也该踏上征程了……”
“是这样……祝福他们吧……圣主您多保重,我们探险队要走了。”
“一路平安……不过走之前我还给你们留了一份纪念品呢~”
“纪念品?这是~!@#$%^&*()_+……一道题!”
给出一个长度为 \(N\) 的由小写字母 'a' \(\sim\) 'z' 和 '*' 组成的字符串 \(A\) ,一个长度为 \(M\) 的仅由小写字母 'a' \(\sim\) 'z' 组成的字符串 \(B\)。一个 '*' 可以匹配任意多个字符(包括 \(0\) 个)。求在 \(B\) 的所有循环同构串中,有多少个能够与 \(A\) 匹配。
循环同构串:就是把 \(B\) 的前 \(k\) 个字母( \(0\le k<M\) )移到结尾所得到的字符串。例如 abc 的循环同构串有 abc 、bca 和 cab。
\(A\) 与 \(B\) 匹配:若除了 \(A\) 中的 '*' 号可以匹配 \(B\) 中的任意多个字符外,其余字符一一对应,则称 \(A\) 与 \(B\) 匹配。例如 a∗b∗c 与 aadbc 是匹配的,其中第一个 ∗ 对应 ad,第二个 ∗ 对应空串。
Input
第一行为字符串 \(A\)。
第二行为字符串 \(B\)。
Output
输出在 \(B\) 的所有循环同构串中,有多少个能够与 \(A\) 匹配。
Sample Input
输入1:
aaaa
aaaa
输入2:
a*a
aaaaaa
输入3:
*a*b*c*
abacabadabacaba
Sample Output
输出1:
4
输出2:
6
输出3:
15
Hint
对于30% 的数据, \(M\le 20\) ;
对于80% 的测试点, \(M\le 200\) ;
对于100% 的测试点, \(1\le N\le 100\ ,\ 1\le M\le 100000\) 。
Solution
KMP
不会
太毒瘤了
Update :
KMP ???
不存在的
我还非要用 Hash 代替 KMP 了。哈希无敌!哈希万岁!
其实原理是一样的。
先将A字符串分成若干个子串,对每个子串计算一遍 Hash 值。(如果是 KMP 就不用这一步)
设 \(f[i][j]\) 表示 \(B\) 字符串从第 \(i\) 个位置之后与 \(A\) 字符串中第 \(j\) 个子串第一次匹配的子串的起始位置。
Hash 可以计算 Hash 值来匹配, KMP 则用 next ,总之算出所有 \(f[i][j]\) 。
将 \(B\) 字符串复制一倍,形成一个环,从而可以遍历所有的循环同构串。
然后从头到尾枚举每个循环同构串,如果发现 \(A\) 的所有子串均能按顺序出现在这个同构串中,就可以匹配, ans++ 。利用 \(f\) 的值,对于第 \(i\) 个 \(B\) 子串只需查看 \(f[i][(\text{ 第 }i-1\ \text{个匹配子串的结束位置 })\ +1]\) 。
KMP
KMP 算法是一种改进的字符串匹配算法。
KMP 算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个 next() 函数实现,函数本身包含了模式串的局部匹配信息。 KMP 算法的时间复杂度 \(O(M+N)\) 。
这篇博客对 KMP 算法有详尽的解释。

浙公网安备 33010602011771号