51Nod1526 分配笔名
分析
在trie树上贪心,将所有串加入trie树中,在深度较深的地方匹配会更优。
由于只需要知道最后的总质量,所以直接取每个点的子树中最大的匹配即可
复杂度\(O(\sum len)\)
加串的时候把路径上\(val\)加\(1\),查询串的时候把沿途\(val\)减\(1\),\(ans\)为减去的\(1\)的个数。
注意\(val\)为\(0\)的情况,如果后面有\(val\)为大于等于\(1\)的点,那么说明这次查询的串比以前查询的串贡献的答案更优,那么就直接加上后面那些\(val\)大于等于\(1\)的点的个数,而不用撤销操作。因为如此计算相当于自动撤销了之前的次优解。不存在次优解到另一分叉而使此串查询路径上\(val\)为\(0\)的情况,因为如果到另一分叉则此串查询路径上至少加了两个串。
代码
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x){
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;
struct Trie
{
static const int SigmaSize=26;
int index(char c)
{
return c-'a';
}
int ch[800010][26];
int val[800010];
int tcnt;
void insert(char*s)
{
int f=0;
while(*s)
{
int c=index(*s);
if(!ch[f][c])
ch[f][c]=++tcnt;
f=ch[f][c];
// cerr<<"*s="<<*s<<" f="<<f<<endl;
++val[f];
++s;
}
}
int query(char*s)
{
int f=0,ans=0;
while(*s)
{
int c=index(*s);
if(!ch[f][c])
return ans;
f=ch[f][c];
if(val[f]>0)
++ans,--val[f];
// else
// return ans; // edit 2 : 不能直接return,相当于撤销之前的操作
++s;
}
return ans; // edit 1 : 保证完全匹配有返回值
}
}T;
char s[800010];
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int n;
read(n);
for(int i=1;i<=n;++i)
{
scanf("%s",s);
T.insert(s);
}
int ans=0;
for(int i=1;i<=n;++i)
{
scanf("%s",s);
ans+=T.query(s);
}
printf("%d\n",ans);
// fclose(stdin);
// fclose(stdout);
return 0;
}
51Nod1526 分配笔名的更多相关文章
- 刷题总结——分配笔名(51nod1526 trie树)
题目: 班里有n个同学.老师为他们选了n个笔名.现在要把这些笔名分配给每一个同学,每一个同学分配到一个笔名,每一个笔名必须分配给某个同学.现在定义笔名和真名之间的相关度是他们之间的最长公共前缀.设笔名 ...
- 51nod 1526 分配笔名(字典树+贪心)
题意: 班里有n个同学.老师为他们选了n个笔名.现在要把这些笔名分配给每一个同学,每一个同学分配到一个笔名,每一个笔名必须分配给某个同学.现在定义笔名和真名之间的相关度是他们之间的最长公共前缀.设笔名 ...
- 51nod 1526 分配笔名
题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 320 难度:7级算法题. 班里有n个同学.老师为他们选了n个笔名.现在要把这些笔名分配给每一个同学,每一 ...
- 51nod 1526 分配笔名(Trie树+贪心)
建出Trie树然后求出一个点子树中有多少笔名和真名.然后贪心匹配即可. #include<iostream> #include<cstring> #include<cst ...
- 51nod-1526-贪心+Trie
题目链接在这 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 320 难度:7级算法题 收藏 关注 班里有n个同学.老师为他们选了n个笔名.现在要把这些笔 ...
- NOIP2018提高组金牌训练营——字符串专题
NOIP2018提高组金牌训练营——字符串专题 1154 回文串划分 有一个字符串S,求S最少可以被划分为多少个回文串. 例如:abbaabaa,有多种划分方式. a|bb|aabaa - 3 个 ...
- mysql 5.7中的用户权限分配相关解读!
这篇文章主要介绍了MySQL中基本的用户和权限管理方法,包括各个权限所能操作的事务以及操作权限的一些常用命令语句,是MySQL入门学习中的基础知识,需要的朋友可以参考下 一.简介 各大帖子及文章都会讲 ...
- 《深入理解Java虚拟机》内存分配策略
上节学习回顾 1.判断对象存活算法:引用计数法和可行性分析算法 2.垃圾收集算法:标记-清除算法.复制算法.标记-整理算法 3.垃圾收集器: Serial:新生代收集器,采用复制算法,单线程. Par ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统-分配角色给用户
系列目录 由于之前做了将权限赋给角色,还需要做将角色组赋给用户,和将用户赋给角色组,一个用户可以拥有多个角色组,一个角色组包含多个用户,打开模块管理,添加一个分配的操作码 并在 角色权限设置授权给他 ...
随机推荐
- C#特征备忘
[assembly:System.CLSCompliant(true)]----利用CLSCompliant属性,可以把程序集标记为与CLS兼容,但仍可以将个别方法的CLSCompliant值设为fa ...
- ps命令各个内容信息详解
USER 用户名 PID 进程ID(Process ID) %CPU 进程的cpu占用率 %MEM 进程的内存占用率 VSZ 进程所使用的虚存的大小(Vi ...
- Necklace CodeForces - 613C (构造)
链接 大意: 给定n种珠子, 第i种有$a_i$个, 求将珠子穿成项链, 使得能使切开后的项链回文的切口尽量多 若有一种以上珠子为奇数, 显然不能为回文, 否则最大值一定是$gcd(a_1,a_2,. ...
- nyoj860(01变形)
http://acm.nyist.net/JudgeOnline/problem.php?pid=860 又见01背包 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 ...
- UVA-701 The Archeologists' Dilemma (数论)
题目大意:给了一个2^E的前缀n,已知前缀n的位数不到2^E的位数的一半,找出满足条件的最小E. 题目解析:设2^E为i位数,则有n*10^i<2^E<(n+1)*10^i.解不等式得到i ...
- HDU 4597 Play Game (记忆化搜索博弈DP)
题意 给出2*n个数,分两列放置,每列n个,现在alice和bob两个人依次从任意一列的对头或队尾哪一个数,alice先拿,且两个人都想拿最多,问alice最后能拿到数字总和的最大值是多少. 思路 4 ...
- oracle图形界面配置tns
oracle图形界面配置tns 启动orcl服务
- Py打包exe报错
Py打包exe报错 下载地址 https://github.com/pyinstaller/pyinstaller 用管理员执行 pip install https:/ ...
- jsp jsp运行原理
JSP的运行原理 每个jsp页面在第一次被访问时,WEB容器都会把请求交给jsp引擎(一个java程序).Jsp 引擎先将jsp翻译成一个_jspServlet实质上也是一个servlet,然后按照 ...
- string logo online customization
url: http://www.asciiarts.net/ example : hello