【学习笔记】[JSOI2019]节日庆典

news/2024/10/18 0:34:34/

我觉得很厉害。因为这道字符串题目的分析非常自然而且并不复杂。

考虑枚举右端点到 r r r时,维护可能成为答案的位置的集合。显然对于相邻两个元素 i , j i,j i,j,我们有 lcp(S[i:],S[j:]) > r − j \text{lcp(S[i:],S[j:])}>r-j lcp(S[i:],S[j:])>rj,否则可以删去 i , j i,j i,j其中之一。画图不难发现我们只需要保证对于任意 k k k,满足 lcp(S[i:],S[k:]) > r − k \text{lcp(S[i:],S[k:])}>r-k lcp(S[i:],S[k:])>rk,也就是只用和第一个位置进行比对。注意 lcp \text{lcp} lcp的长度是不随右端点 r r r变化的,可以看成常数。

当然,上述分析并不能导向一个正确的解法。假设我们已经维护出来了上述集合,有一个非常套路的想法,假设已经检查完了 i i i之前的所有位置,那么对于之后的一个位置 j j j,假设 j − i < r − j j-i<r-j ji<rj,那么不难发现 S [ i : j ) = S [ j : 2 j − i ) S[i:j)=S[j:2j-i) S[i:j)=S[j:2ji),我们记这一段为 A A A(更确切地说 A A A S [ i : r ] S[i:r] S[i:r]的周期), 2 j − i 2j-i 2ji以后的为 B B B,那么我们得到 A + A + B , A + B + A , B + A + A A+A+B,A+B+A,B+A+A A+A+B,A+B+A,B+A+A三种方案。容易观察出中间那种肯定是不优的,也就是 j j j一定不优。那么有 2 j ≥ r + i 2j\ge r+i 2jr+i,显然只有最多 log ⁡ \log log个需要检查,这道题就做完了。因为 lcp \text{lcp} lcp已经匹配到了底所以用 z z z函数辅助检查一下即可。

复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)

代码咕了。其实是我不会打 z z z函数

至于维护集合那个部分,可以自己编一个做法,事实上发现每次暴力重构就完了。

#include<bits/stdc++.h>
#define pb push_back
#define ll long long
using namespace std;
const int N=3e6+5;
int n,z[N],res;
string s;
vector<int>f,g;
int solve(int pos1,int pos2,int last){if(pos1==-1)return 1;pos1+=last-pos2+1;if(z[pos1]<last-pos1+1){return s[z[pos1]]<s[pos1+z[pos1]];}pos1=last-pos1+1;if(pos1+z[pos1]>=pos2)return 0;return s[z[pos1]]>s[pos1+z[pos1]];
}
void ins(int pos,int last){while(g.size()&&s[g.back()+last-pos]!=s[last]){if(s[g.back()+last-pos]<s[last])return;g.pop_back();}if(!g.size()||2*pos>=last+g.back()){g.pb(pos);}
}
int main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>s,n=s.size();for(int i=1,l=0,r=0;i<n;i++){if(r>=i&&z[i-l]<r-i+1)z[i]=z[i-l];else{z[i]=max(0,r-i+1);while(i+z[i]<n&&s[i+z[i]]==s[z[i]])z[i]++;}if(i+z[i]-1>r)l=i,r=i+z[i]-1;}for(int i=0;i<n;i++){g.clear(),res=-1;for(auto x:f)ins(x,i);ins(i,i),f=g;for(auto x:g){if(solve(res,x,i))res=x;}cout<<res+1<<" ";}
}

http://www.ppmy.cn/news/47231.html

相关文章

SSM整合的基本思路梳理

SSM整合的简单思路流程 基本思路 我在整合的时候一般习惯从MyBatis开始向上构建&#xff0c;也就是在开始一个项目的时候先将DAO层搭建起来&#xff0c;再向上整合Spring以及SpringMVC。按照这个流程&#xff0c;可以做出一个比较简单的大致流程作为参考&#xff0c;帮助我们…

【MyBatis Plus】003 -- 配置(基本、进阶、DB策略) 条件构造器

目录 4、配置 4.1 基本配置 4.1.1 configLocation &#xff08;MyBatis 配置文件位置&#xff09; 4.1.2 mapperLocations&#xff08;MyBatis Mapper 所对应的 XML 文件位置&#xff09; 4.1.3 typeAliasesPackage &#xff08;别名包扫描路径&#xff09; 4.2 进阶配置 4.2.1…

图解项目延期的原因及解决应对方案大全

项目管理中经常出现项目延期的情况&#xff0c;面对项目延期的风险如何应对是考验每个项目经理管理水平的时候&#xff0c;很多人纵然是工作多年也没有对延期的种种情况进行总结思考。 咱们社区的小竹对大家常见的项目延期情况及处理方案进行了详细全面的总结&#xff0c;供大…

Kotlin 泛型的使用

一、Kotlin 泛型是一种允许在编译时指定类型参数的机制&#xff0c;它可以提高代码的重用性和类型安全性。 Kotlin 泛型使用尖括号&#xff08;< >&#xff09;来指定类型参数。Kotlin 泛型支持类泛型、接口泛型和方法泛型。Kotlin 泛型可以在类、函数、接口和委托中使用…

Linux命令行操作/选项介绍,文件分类/内容与属性/绝对相对路径,隐藏文件与整个目录结构

Linux的命令行操作介绍 Linux操作的特点&#xff1a;纯命令行&#xff0c;当然Linux它也有图形化界面或桌面版。Windows也有命令行&#xff0c;也有图形化界面。不过它是面向普通客户的操作系统&#xff0c;所以必须得是好用好玩的&#xff0c;所以图形化界面那是必然。无论是…

Linux-初学者系列——篇幅3_操作界面获取帮助

操作界面获取帮助-目录 1、获取帮助信息-man2、获取帮助信息-help3、获取帮助信息-info 上篇: Linux-初学者系列——篇幅2_系统命令界面 利用帮助命令自学&#xff1a;man help info1、获取帮助信息-man 查看命令和部分文件帮助说明信息 使用方法&#xff1a; man [参数选项…

PHP快速入门07-Cookie与Session的说明与使用

文章目录 前言一、关于Cookie和Session1.1 Cookie1.2 Session 二、Cookie和Session的使用2.1 Cookie的使用例子2.2 Session的使用例子 总结 前言 本文已收录于PHP全栈系列专栏&#xff1a;PHP快速入门与实战 Cookie和Session是一个Web开发几乎不可避免的东西&#xff0c;是网站…

【Linux网络设置】

目录 一、查看网络接口信息1.1、查看所有活动的网络接口信息1.2、查看指定网络接口信息 二、查看主机名称2.1、hostname命令2.2、永久设置主机名 三、查看路由表条目route命令 四、查看网络连接情况4.1、netstat命令4.2、ss命令 五、测试网络连接ping命令 6、跟踪数据包tracerr…