cogs2223. [SDOI2016 Round1] 生成魔咒(后缀数组 hash 二分 set
题意:对一个空串每次在后面加一个字符,问每加完一次得到的字符串有几个不同的子串。
思路:每个子串都是某个后缀的前缀,对于每个后缀求出他能贡献出之前没有出现过的前缀的个数,答案累加就行。
要求每个后缀的贡献,就是这个后缀的长度减去此前的后缀与该后缀的LCP的最大值,这个最大值是height[i]。
至于怎么找出先前的能与该后缀生成最大LCP的后缀,可以用set维护,将cmp函数自定义成按字典序从小到大,
那么目标后缀就是当前后缀的前趋或后继,求两次LCP并更新答案即可。字符串hash用来比较,二分答案找LCP的值,
另外s.insert(i).first能返回把元素i插入到s中的地址(迭代器)。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const int maxn=200000;
const ULL BASE=1e9+7;
int N,now;
ULL a[maxn],base[maxn],has[maxn],ANS; inline ULL get_hash(ULL from,ULL len){
return has[from]-has[from+len]*base[len];
}
inline int find(int l,int r,int f1,int f2){
if(l+1>=r) {
if(get_hash(f1,r)==get_hash(f2,r)) return r;
else return l;
}
int mid = (l+r)>>1;
if(get_hash(f1,mid)==get_hash(f2,mid))
return find(mid,r,f1,f2);
else return find(l,mid-1,f1,f2);
} struct cmp{
bool operator()(const int &aa,const int &bb){
int len = find(0,1e5,aa,bb);
return a[aa+len]<a[bb+len];
}
};
set<int,cmp> S;
set<int,cmp>::iterator tmp1,tmp2;
int main(){
freopen("menci_incantation.in","r",stdin);
freopen("menci_incantation.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>N;
base[0] = 1;
for(int i=1;i<=N;i++) base[i] = base[i-1]*BASE;
for(int i=N;i>=1;i--){
cin>>a[i];
now = 0;
has[i] = has[i+1]*BASE+a[i];
tmp1 = S.insert(i).first;
tmp2 = tmp1;
if(tmp1!=S.begin()){
tmp1--;
now = find(0,1e5,i,*tmp1);
}
if(++tmp2!=S.end()){
now = max(now,find(0,1e5,i,*tmp2));
}
ANS += (ULL)N-i+1-now;
cout<<ANS<<endl;
}
return 0;
}
cogs2223. [SDOI2016 Round1] 生成魔咒(后缀数组 hash 二分 set的更多相关文章
- cogs2223 [SDOI2016 Round1] 生成魔咒
cogs2223 [SDOI2016 Round1] 生成魔咒 原题链接 题解 暴力:每次更新后缀数组??? set+二分+hash暴力 http://paste.ubuntu.com/2549629 ...
- liberOJ #2033. 「SDOI2016」生成魔咒 后缀数组
#2033. 「SDOI2016」生成魔咒 题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1 11.2 22 拼凑起来形成一个魔咒串 [1,2] [1, 2] ...
- [SDOI2016] 生成魔咒 - 后缀数组,平衡树,STL,时间倒流
[SDOI2016] 生成魔咒 Description 初态串为空,每次在末尾追加一个字符,动态维护本质不同的子串数. Solution 考虑时间倒流,并将串反转,则变为每次从开头删掉一个字符,即每次 ...
- 【bzoj4516】[Sdoi2016]生成魔咒 后缀数组+倍增RMQ+STL-set
题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2].一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例如 S=[1,2 ...
- cogs 2223. [SDOI2016 Round1] 生成魔咒
★★☆ 输入文件:menci_incantation.in 输出文件:menci_incantation.out 简单对比 时间限制:1 s 内存限制:128 MB [题目描述]魔咒串由许多魔咒字符组 ...
- BZOJ.4516.[SDOI2016]生成魔咒(后缀数组 RMQ)
题目链接 后缀自动机做法见这(超好写啊). 后缀数组是可以做的: 本质不同的字符串的个数为 \(子串个数-\sum_{ht[i]}\),即 \(\frac{n(n+1)}{2}-\sum_{ht[i] ...
- BZOJ 4516: [Sdoi2016]生成魔咒——后缀数组、并查集
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4516 题意 一开始串为空,每次往串后面加一个字符,求本质不同的子串的个数,可以离线.即长度为 ...
- BZOJ 4516: [Sdoi2016]生成魔咒(后缀数组)
传送门 解题思路 题目其实就是动态维护本质不同的串的个数.考虑到只有加数字的操作,所以可以用后缀数组.题目是每次往后加数字,这样不好处理,因为每次加数字之后所有的后缀都会改变.所以要转化一下思路,就是 ...
- BZOJ4516: [Sdoi2016]生成魔咒(后缀数组 set RMQ)
题意 题目链接 Sol 毒瘤SDOI 终于有一道我会做的题啦qwq 首先,本质不同的子串的个数 $ = \frac{n(n + 1)}{2} - \sum height[i]$ 把原串翻转过来,每次就 ...
随机推荐
- git基础学习
1.git是什么 内容寻址文件系统,分布式版本控制系统 2.git作用 开发过程中的版本控制 3.git基础命令 克隆git仓库---clone:git clone 仓库url 选分支---check ...
- Skier 游戏
# Listing_10-1.py # Copyright Warren Sande, 2009 # Released under MIT license http://www.opensource. ...
- 【Sublime】设置显示编码格式
Mac 上的 Sublime 显示编码格式,设置方法: 右下角显示的 UTF-8 就是当前的编码格式. 添加如下代码: { "font_size": 18, // Display ...
- 【iOS】Interface Builder 预览
Interface Builder 为最顶层视图提供了 Simulated Metrics,预览用户界面的各种外观设置效果,例如顶部有导航栏或底部有标签栏的效果,如图所示:
- Asp.Net MVC SingleServiceResolver类剖析
SingleServiceResolver一般用于类工厂创建和注入点接口留白.类工厂创建比如Controller控制依赖于此类的创建,注入点留白实质上是依赖注入所对外预留的接口. 以第二个特性为例. ...
- DesignPattern系列__03依赖倒置原则
依赖倒置原则(Dependence Inversion Priiciple,DIP) 介绍 High level modules should not depend upon low level mo ...
- HTML5 第二章 列表和表格和媒体元素
列表: (1)什么是列表? 列表就是信息资源的一种展示形式. (2)无序列表: 语法: <ul> <li>第1项</li> <li>第2项</li ...
- 算法与数据结构基础 - 链表(Linked List)
链表基础 链表(Linked List)相比数组(Array),物理存储上非连续.不支持O(1)时间按索引存取:但链表也有其优点,灵活的内存管理.允许在链表任意位置上插入和删除节点.单向链表结构一般如 ...
- Go中的指针
学Java以来,让程序员忽略了指针和内存地址这些概念,Java帮我们封装了对象,简化了对象引用之间的关系.在Go语言中,又帮我们回忆起这些概念. 我们创建的每一个对象在内存中都有一个位置去存储,每个内 ...
- resolv.conf文件配置相关的案例
引言 操作系统中/etc/resolv.conf配置文件中的内容一般为空,如果该文件配置不正确,将导致ssh.route.netstat命令响应慢的问题. 在/etc/resolv.conf添加错误地 ...