CodeChef | September Challenge 2013 | To Queue or not to Queue

本文介绍了一种解决特定字符串操作问题的方法,通过维护后缀数组和使用集合与链表的数据结构,实现了对字符串进行添加和删除字符操作的同时,高效地计算不同子串的数量。

题目大意:

两种操作:

对字符串s(初始为空串)

1: 在s末尾加一个小写字母

2:删除s的第一个元素(保证删除后s非空)

每完成一个操作,记sum[i]为当前s串的不同子串, 求sigma{sum[i]}

...比赛期间怎么也想不到做法...基本上乱七八糟的做法都想过...还是不会...

后来看了ACRush的代码,终于会了...


做法如下:

记串[i,n) 为suffix[i]

---------

以样例来演示:

8
+ a
+ b
+ a
+ a
-
-
-
+ a


得到串"abaaa"

求一次后缀数组,得到

a
aa
aaa
abaaa
baaa


当前s=0, t=-1


+ a

---------

s = 0, t = 0

加入suffix[0]

a | baaa  (0)   ( | 用来划分有效长度)


+ a

---------

s = 0, t = 1

加入suffix[1]

ab | aaa  (0)

b | aaa  (1)


+ a

---------

s = 0, t = 2

加入suffix[2]

a | aa (2)

aba | aa (0)

ba | aaa (1)


+ a 

---------

s = 0, t = 3

加入suffix[3]

a | a (3)

aa | a (2)

abaa | a (0)

baaa | a (1)


-

---------

s = 1, t = 3

删除suffix[0]

a | a (3)

aa | a (2)

baaa | a (1)


-

---------

s = 2, t = 3

删除suffix[1]

a | a (3)

aa | a (2)


-

---------

s = 3, t = 3

删除suffix[2]

a | a  (3)

+ a

---------

s = 3, t = 4

加入suffix[4]

a (4)

aa (3)


以上操作可以通过 set  + 链表实现

set<int>::iterator e = S.lower_bound(rank[g]);
if(e == S.begin()) pre = n;
else pre = sa[*(--e)];

那么现在要做的就是完成以上操作的同时得到不同子串个数。

记子串个数为cur

记与以前重复的串个数为over

记答案为ans


对于 + 操作

我们插入suffix[t]

那么

更新链表/set

over -= lcp(pre[t], next[t]);

over += lcp(pre[t], t)

over += lcp(t, next[t])

同时要注意。如果lcp(pre[t], t) 或者 lcp(t, next[t])大于suffix[t]的有效长度,则暂不插入。因为当前来说这个串及它后面的串都是重复串。

简单证明如下。suffix[t+1] 是 suffix[t]的子串, 现在suffix[t]是 某个串的子串, 则suffix[t+1]也是某个串的子串。

对于 - 操作

更新链表/set

over -= lcp(pre[t], t)

over -= lcp(t, next[t])

over += lcp(pre[t], next[t])

cur 可以通过简单计算得到

ans += cur - over


搞定~



在 YARN 中,“`root is not a leaf queue`”错误通常出现在尝试向 YARN 提交作业时,表明当前调度器的队列配置存在问题。此错误的核心在于 YARN 的队列层级结构中,**leaf queue(叶队列)** 是唯一可以实际接收任务的队列类型,而非叶节点队列(如父队列或中间队列)不能直接分配任务资源[^2]。 ### YARN 队列结构与调度机制 YARN 的调度器支持分层队列结构,其中 `root` 是整个队列树的根节点。该结构允许将资源按照组织单位、用户组或优先级进行划分。例如: ```text root ├── finance │ ├── analysts │ └── reports └── engineering ├── backend └── frontend ``` 在该结构中,只有 `analysts`、`reports`、`backend` 和 `frontend` 是叶队列。如果提交任务时指定的队列是 `root` 或 `finance` 等非叶队列,YARN 将拒绝任务并抛出 `root is not a leaf queue` 错误。 ### 常见触发场景 1. **作业提交时指定错误队列** 用户在提交作业时可能误将队列指定为非叶队列,例如: ```bash hadoop jar hadoop-mapreduce-client-jobclient-*.jar TestDFSIO \ -write -nrFiles 10 -size 10MB \ -D mapreduce.job.queuename=root ``` 此时作业将无法提交,并抛出该错误。 2. **默认队列配置不当** 如果未在 `yarn-site.xml` 中正确配置默认队列(`yarn.scheduler.capacity.default-queue`),系统可能尝试将作业提交到 `root` 队列。 3. **调度器配置错误** 在 `fair-scheduler.xml` 或 `capacity-scheduler.xml` 中,如果未正确设置叶队列属性,也可能导致调度器无法识别叶队列[^2]。 ### 解决方案 1. **确保作业提交到叶队列** 修改作业提交命令,确保 `-D mapreduce.job.queuename` 指定的是叶队列: ```bash -D mapreduce.job.queuename=finance.analysts ``` 2. **检查并设置默认队列** 在 `yarn-site.xml` 中设置默认队列为叶队列: ```xml <property> <name>yarn.scheduler.capacity.default-queue</name> <value>engineering.backend</value> </property> ``` 3. **验证调度器配置文件** 在 `fair-scheduler.xml` 中,确保每个队列的 `type` 属性为 `fair` 或 `fifo`,并且非叶队列必须设置为 `parent` 类型: ```xml <queue name="finance" type="parent"> <queue name="analysts" type="fair"/> <queue name="reports" type="fair"/> </queue> ``` 在 `capacity-scheduler.xml` 中,确保每个队列层级的 `capacity` 和 `leaf-queue-per-user-limit` 等参数配置正确。 4. **重启 YARN 服务** 修改配置后,重启 ResourceManager 和 NodeManager 服务以确保配置生效。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值