3294 [SCOI2016]背单词
题目描述
Lweb 面对如山的英语单词,陷入了深深的沉思,”我怎么样才能快点学完,然后去玩三国杀呢?“。这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的:
—————序号 单词—————
1 2......n-2n-1 n—————
然后凤老师告诉 Lweb ,我知道你要学习的单词总共有 n 个,现在我们从上往下完成计划表,对于一个序号为 x 的单词(序号 1...x-1 都已经被填入):
- 如果存在一个单词是它的后缀,并且当前没有被填入表内,那他需要吃 n*n 颗泡椒才能学会;
- 当它的所有后缀都被填入表内的情况下,如果在 1...x-1 的位置上的单词都不是它的后缀,那么你吃 x 颗泡椒就能记住它;
- 当它的所有后缀都被填入表内的情况下,如果 1...x-1的位置上存在是它后缀的单词,所有是它后缀的单词中,序号最大为 y ,那么你只要吃 x-y 颗泡椒就能把它记住。
Lweb 是一个吃到辣辣的东西会暴走的奇怪小朋友,所以请你帮助 Lweb ,寻找一种最优的填写单词方案,使得他记住这 n 个单词的情况下,吃最少的泡椒。
输入输出格式
输入格式:
输入一个整数 n ,表示 Lweb 要学习的单词数。
接下来 n 行,每行有一个单词(由小写字母构成,且保证任意单词两两互不相同)1<=n<=100000, 所有字符的长度总和 1<=|len|<=510000
输出格式:
Lweb 吃的最少泡椒数
输入输出样例
2
a
ba
2
Solution:
写这题博客我是真的要无语了,昨晚写了一半结果保安拉闸断电,今早重写完了结果考试断网没发,关键是后面考完我常规操作关机了,这是第三遍写这题博客了。
先是吐槽,题意真的晦涩。
再简述下题意:本题就是给定n个字符串,然后需要确定它们的先后顺序使得总花费最少,对于第i个字符串,花费有3种情况:
1、字符串中有第i个字符串的后缀,且没有排在i之前,花费为i*i
2、字符串中没有第i个字符串的后缀,花费为i
3、字符串中有第i个字符串的后缀且全部排在i之前,花费为i-最近的是它后缀的字符串的排名k
思路:trie+贪心dfs。
首先对于判断一个串是另一个串的后缀,很容易想到fail,自然就能选用AC自动机了,当然本题不需要那么麻烦,我们可以把单词反转,题目就变成了判断前缀,于是就能加入trie树中去做。
贪心的想到,我们要尽可能避免第1种情况,若把空字符当作任意字符串的前缀且排名为0,那么第2种情况可以看作特殊的第3种情况,那么对于一个单词节点,要使花费最小,那么就要让它的最长前缀的排名尽可能接近,我们处理出每个单词节点的最长前缀位置并连边,形成的是一棵以0为根的树,题目转化为给这棵树节点标号且子节点标号要大于父节点标号,然后最小化子节点标号-父节点标号的差的和。
再贪心去想,很显然父子节点标号要尽量差值小,那么每次我们都往当前最小的子树走,并标号,可以保证下次回到初节点去标记其它子树节点时,使得初节点和子节点差值接近。
以这个贪心思想去求,最后只要统计答案就好了。
代码:
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/priority_queue.hpp>
#define il inline
#define ll long long
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
using namespace std;
using namespace __gnu_pbds;
const int N=;
int n,ch[N][],cnt,pre[N],num[N];
int to[N],net[N],h[N],Cnt,siz[N];
ll ans;
bool ed[N];
char s[N];
struct node{
int u,d;
node(int a=,int b=){u=a,d=b;}
bool operator<(const node &a)const {return d>a.d;}
}; il void insert(char *s,int id){
int len=strlen(s),p=,x;
Bor(i,,len-){
x=s[i]-'a';
if(!ch[p][x])ch[p][x]=++cnt,pre[cnt]=p;
p=ch[p][x];
}
ed[p]=,num[id]=p;
} il void add(int u,int v){to[++Cnt]=v,net[Cnt]=h[u],h[u]=Cnt;} il void dfs(int u){
siz[u]=;
for(int i=h[u];i;i=net[i])
dfs(to[i]),siz[u]+=siz[to[i]];
} __gnu_pbds::priority_queue<node,less<node>,pairing_heap_tag>q,Q; il void cal(int u){
for(int i=h[u];i;i=net[i])q.push(node(to[i],siz[to[i]]));
while(!q.empty()){
node x=q.top();q.pop();
num[x.u]=++cnt;
cal(x.u);
}
} il void query(int u){
for(int i=h[u];i;i=net[i]){
ans+=num[to[i]]-num[u];
query(to[i]);
}
} int main(){
scanf("%d",&n);
For(i,,n) scanf("%s",s),insert(s,i);
For(i,,n) {
int p=pre[num[i]];
while(p&&!ed[p])p=pre[p];
add(p,num[i]);
}
int p=cnt;
memset(num,,sizeof(num));
dfs(),cnt=,cal(),query();
cout<<ans;
return ;
}
3294 [SCOI2016]背单词的更多相关文章
- BZOJ4567[Scoi2016]背单词
4567: [Scoi2016]背单词 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 304 Solved: 114 [Submit][Status] ...
- P3294 [SCOI2016]背单词
P3294 [SCOI2016]背单词 Trie+贪心 倒插进树+取出重建+子树处理+贪心遍历 倒插进树:把后缀转化为前缀,所以把字符串倒着插进Trie中 取出重建:重新建立一棵以单词为节点的树,如果 ...
- 4567: [Scoi2016]背单词
4567: [Scoi2016]背单词 https://www.lydsy.com/JudgeOnline/problem.php?id=4567 题意: 题意看了好久,最后在其他人的博客里看懂了的. ...
- 【BZOJ4567】[Scoi2016]背单词 Trie树+贪心
[BZOJ4567][Scoi2016]背单词 Description Lweb 面对如山的英语单词,陷入了深深的沉思,“我怎么样才能快点学完,然后去玩三国杀呢?”.这时候睿智 的凤老师从远处飘来,他 ...
- 【bzoj4567】[Scoi2016]背单词
4567: [Scoi2016]背单词 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1123 Solved: 476[Submit][Status][ ...
- [SCOI2016]背单词——trie树相关
题目描述 Lweb 面对如山的英语单词,陷入了深深的沉思,”我怎么样才能快点学完,然后去玩三国杀呢?“.这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的: ...
- [SCOI2016]背单词 题解
背单词 https://www.luogu.com.cn/problem/P3294 前言: Trie树的省选题(瑟瑟发抖QAQ) 问题汇总:(请忽略) (1)对Trie字典树的运用不熟练 (2)没想 ...
- [BZOJ4567][SCOI2016]背单词(Trie+贪心)
1.题意表述十分难以理解,简单说就是:有n个单词,确定一个背的顺序,使总代价最小. 2.因为第(1)种情况的代价是n*n,这个代价比任何一种不出现第(1)种情况的方案都要大,所以最后肯定不会出现“背某 ...
- [SCOI2016]背单词
题目描述 Lweb 面对如山的英语单词,陷入了深深的沉思,”我怎么样才能快点学完,然后去玩三国杀呢?“.这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的: ...
随机推荐
- 12、Java并发编程:阻塞队列
Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...
- Drupal views 学习之初识
1. 简介 用过Yii框架的同学,应该都会用到过GridView和ListView组件.可以很方便的用网格或列表展示内容. 例如淘宝: 网格显示 列表显示 2. 使用view可以方便的配出类似上面的展 ...
- 洛谷P2464 [SDOJ2008]郁闷的小J
洛谷P2464 [SDOJ2008]郁闷的小J 题目描述 小J是国家图书馆的一位图书管理员,他的工作是管理一个巨大的书架.虽然他很能吃苦耐劳,但是由于这个书架十分巨大,所以他的工作效率总是很低,以致他 ...
- 如何运用 Powershell 修改Office365和AD账户
这段时间需要大量地修改AD用户的一些属性,例如邮件,UPN,登录名等等,以便和Office365的登录账号保持一致.写了个简单脚本进行批量修改. #Import AD ModuleImport-Mod ...
- Vue 编程之路(一)——父子组件之间的数据传递
最近公司的一个项目中使用 Vue 2.0 + element UI 实现一个后台管理系统的前端部分,属于商城类型.其中部分页面是数据管理页,所以有很多可以复用的表格,故引入自定义组件.在这里分享一下开 ...
- 169.求众数 leetcode Javascript
给定一个大小为 n 的数组,找到其中的众数.众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是非空的,并且给定的数组总是存在众数. 示例 1: 输入: [3,2,3] 输出: 3 ...
- Node开发项目管理工具 Grunt 对比 Gulp
转自Gulp vs Grunt 1. Grunt -> Gulp 早些年提到构建工具,难免会让人联想到历史比较悠久的Make,Ant,以及后来为了更方便的构建结构类似的Java项目而出现的Mav ...
- Debian 9 + Windows 10 双系统安装体验
很久之前就想在自己的电脑上也装个 Debian 玩玩了,最近正好有时间折腾,就踩了踩坑在笔记本上装了玩玩~ UEFI + GPT 解决启动相关的麻烦配置 如果在支持 UEFI 的电脑上安装 Debia ...
- spark的数据结构 RDD——DataFrame——DataSet区别
转载自:http://blog.csdn.net/wo334499/article/details/51689549 RDD 优点: 编译时类型安全 编译时就能检查出类型错误 面向对象的编程风格 直接 ...
- php 中关于pdo的使用
之前一段时间,开始了php的研究,看了关于PDO的一些资料,发现不错,整理和总结一下,作为开发笔记,留待日后使用,<PHP开发笔记系列(一)-PDO使用>. PDO是PHP Data Ob ...