Pref 社论
题面
一个长度为 \(k\) 字符串序列 \(s\) 是好的,当且仅当 \(\forall 1\le i<k\),有 \(B_i\) 既是 \(B_{i+1}\) 的前缀,又是 \(B_{i+1}\) 的后缀 .
给一个字符串序列 \(A\),求其最长好子序列 .
数据范围:\(\displaystyle \sum_k |A_k|\le 2\times 10^6\)
时限 \(2\ \rm s\),空限 \(512\rm\ MB\) .
题解
算法 1
考虑 dp .
令 \(dp_i\) 表示以 \(A_i\) 结尾的最长好序列,于是可以暴力转移 .
时间复杂度 \(O(n^3)\),期望 \(20\sim 40pts\) .
算法 2
考虑加速算法 \(1\) 中转移过程 .
字符串 Hash 处理每个子串的 border,同时构建映射 \(\mathrm M:\,border\to dp\) .
一轮 dp 可以线性完成,映射可以考虑两种实现方式
方式编号 | 表现 \(1\) | 表现 \(2\) | 时间复杂度 |
---|---|---|---|
\(1\) | std::map |
平衡树 | \(O(n\log n)\) |
\(2\) | std::unordered_map |
Hash Table | \(O(n)\) |
期望 \(100pts\) .
算法 3(标答)
记 \(\overline s\) 为 \(s\) 逆序排成的字符串 .
于是 \(s\) 是 \(t\) 的后缀等价于 \(\overline s\) 是 \(\overline t\) 的前缀 .
现在我们有两个前缀关系,建 Trie 树并且在 Trie 树上 dp 即可 .
期望 \(100pts\) .
代码
算法 1
20pts(by jijidawang)
using namespace std;
typedef long long ll;
const int N = 1e6 + 500;
int n;
ll p, dp[N];
string s[N];
inline bool pure_chk(string a, string b)
{
int la = a.length(), lb = b.length();
if (la > lb) return false;
for (int i=0; i<la; i++)
if (a[i] != b[i]) return false;
return true;
}
inline bool chk(string a, string b)
{
bool ans = pure_chk(a, b);
reverse(b.begin(), b.end());
return ans & pure_chk(a, b);
}
int main()
{
scanf("%d", &n);
for (int i=1; i<=n; i++) cin >> s[i];
dp[1] = 1;
for (int i=2; i<=n; i++)
for (int j=1; j<i; j++)
if (chk(s[j], s[i])) dp[i] = max(dp[i], dp[j]+1);
ll ans = 0;
for (int i=1; i<=n; i++) ans = max(ans, dp[i]);
printf("%lld\n", ans);
return 0;
}
40pts(by Rolling_Star)
using namespace std;
int n,dp[2000001];
string s[2000001];
bool flag;
inline bool check(int x,int y);
int main()
{
cin>>n;
for(register int i=1;i<=n;i++)
cin>>s[i];
int ans=0;
dp[1]=1;
for(register int i=2;i<=n;++i)
{
dp[i]=1;
for(register int j=1;j<=i-1;++j)
if(s[i].size()>=s[j].size())
if(check(i,j))
dp[i]=max(dp[i],dp[j]+1);
ans=max(ans,dp[i]);
}
cout<<ans;
}
inline bool check(int x,int y)
{
for(register int i=0;i<s[y].size();++i)
if(s[y][i]!=s[x][i])
return false;
for(register int i=s[x].size()-s[y].size(),j=0;j<s[y].size();++i,++j)
if(s[y][j]!=s[x][i])
return false;
return true;
}
算法 2
using namespace std;
const int N = 1e6 + 500;
typedef long long ll;
typedef char str[N];
const ll P = 1e9+7, base = 131;
int n;
ll pb[N];
str s;
map<ll, int> dp;
int main()
{
scanf("%d", &n);
pb[0] = 1;
for (int i=1; i<N; i++) pb[i] = pb[i-1] * base % P;
int ans = 0;
for (int i=1; i<=n; i++)
{
scanf("%s", s+1); int l = strlen(s+1);
ll p=0, ss=0; int H=0;
for (int j=1; j<=l; j++)
{
p = (p*base % P + s[j]) % P;
ss = (ss + s[l-j+1]*pb[j-1] % P) % P;
if (p == ss) H = max(H, dp[p]);
}
dp[p] = max(dp[p], H+1);
ans = max(ans, dp[p]);
} printf("%d\n", ans);
return 0;
}
算法 3
Pref 社论的更多相关文章
- @ConfigurationProperties(pref="")加载局部配置文件
刚开始@ConfigurationProperties(文件名)直接在参数里加文件名,其实是配置前缀pref="前缀".加载局部配置文件是@PropertySource(value ...
- Chrome Switchs & Chrome Pref
Chrome Switchs: https://chromium.googlesource.com/chromium/src/+/master/chrome/common/chrome_switche ...
- 丽泽普及2022交流赛day20 1/4社论
目录 T1 正方形 T2 玩蛇 T3 嗷呜 T4 开车 T1 正方形 略 T2 玩蛇 略 T3 嗷呜 (插一个删一个?) 找出相同的,丢掉循环节 . 感觉非常离谱,,, 正确性存疑 正确性问 SoyT ...
- Minimax 社论
目录 题面 题解 代码 Reference 题面 LOJ #2537 / 洛谷 P5298 「PKUWC2018」Minimax 一棵有根二叉树 \(\mathcal T\) . 定义结点 \(x\) ...
- 丽泽普及2022交流赛day22 无社论
开始掉分模式 . T3 有人上费用流了???(id) 不用 TOC 了 . T1 暴力 T2 没看见 任意两圆不相交,gg 包含关系容易维护,特判相切 . 单调栈即可 T3 贪心 T4 神秘题
- 丽泽普及2022交流赛day21 社论
A 暴力 . greater<double> -> greater<int> \(100\) -> \(50\) 代码丢了 . B dp . 考场上代码抢救一下就过 ...
- 丽泽普及2022交流赛day19 半社论
目录 No Problem Str Not TSP 题面 题解 代码 Game 题面 题解 代码 No Problem 暴力 Str 存在循环节,大力找出来即可,长度显然不超过 \(10^3\) . ...
- 丽泽普及2022交流赛day18 社论
A 暴力扫一遍 B 算法 0 似乎是二分 算法 1 随便贪心 C 算法 1 枚举一个点作为最大值 / 最小值,用单调栈维护其作为答案的左右端点即可轻易计算 . 时间复杂度 \(O(n)\) . 算法 ...
- 膜 社论(egg drop)
题面 \(n\) 楼 \(m\) 个鸡蛋,从 \(k\) 楼及以上扔下去会碎,不能再测试 . 问至少需要扔几次确定 \(k\) . \(n\le 10^{18}\),\(m\le 64\) . 题解 ...
随机推荐
- mybatis各阶段的详解
1 本阶段的需要注意的几个点 1,首先是在核心配置文件里面的内容: 配置的顺序,不配则不用管,配则必须按顺序来!!!! properties?, settings?, typeAliases?, ty ...
- 溢出属性,定位,z-index,JS
溢出属性 1.visible(默认值):使溢出内容展示 2.hidden:隐藏溢出内容且不出现滚动条 3.scroll:隐藏溢出容器的内容,溢出的内容可以通过滚动呈现 4.auto:与scroll没啥 ...
- CI/CD介绍以及jenkins安装 1.1
一 .CI/CD介绍 互联网软件开发和发布,形成了一套流程标准,分为几个阶段:编码,构建,集成,测试,交付,部署 持续集成(continuous integration).持续交付(conti ...
- 个人冲刺(二)——体温上报app(二阶段)
冲刺任务:完成app首页.第二页面和特殊情况的页面布局 activity_main.xml <?xml version="1.0" encoding="utf-8& ...
- 如何使用picGo+typora配置云笔记
PicGo的使用 安装 picGo 2.3版本 (window可用)---官网有点慢,已经下载到个人仓库 https://gitee.com/lht1132950411/study/blob/mast ...
- 《Unix 网络编程》08:基本UDP套接字编程
基本UDP套接字编程 系列文章导航:<Unix 网络编程>笔记 UDP 概述 流程图 recvfrom 和 sendto #include <sys/socket.h> ssi ...
- CF1485E Move and Swap
题意:Move and Swap 很好的题呢 n个节点的树,根为1,所有叶子的深度都是D,一开始根节点上有两个颜色分别微R,B的球,你执行下列操作D-1次: 1.R点跳到子树内 2.B点跳到下一层的任 ...
- ClickHouse(01)什么是ClickHouse,ClickHouse适用于什么场景
ClickHouse的由来 ClickHouse是什么数据库?ClickHouse速度有多快?应用场景是怎么样的?ClickHouse是关系型数据库吗?ClickHouse目前是很火爆的一款面向OLA ...
- Python中plt.plot()、plt.scatter()和plt.legend函数的用法示例
参考:http://www.cppcns.com/jiaoben/python/471948.html https://blog.csdn.net/weixin_44825185/article/de ...
- Eureka入门
一个Eureka中分为eureka server和eureka client.其中eureka server是作为服务的注册与发现中心.eureka client既可以作为服务的生产者,又可以作为服务 ...