cogs2223 [SDOI2016 Round1] 生成魔咒
cogs2223 [SDOI2016 Round1] 生成魔咒
原题链接
题解
暴力:每次更新后缀数组???
set+二分+hash暴力 http://paste.ubuntu.com/25496298/
正解:把串反过来,答案不变,但每次只需插入一个后缀。
先预处理出整个后缀数组,然后set插入。
len=n时,\(ans=\frac{n(n+1)}{2}-\sum ht[i]\)
Code
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<set>
#include<cmath>
#define Fname "magic"
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
#define mp make_pair
#define pr pair<unsigned int,ll>
typedef long long ll;
il int gi(){
rg int x=0;rg char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x;
}
const int maxn=600100;
int c[maxn],data[maxn],n,tot;
struct node{int l;};
il node Make(int a){return(node){a};}
set<node>s;
int sa[maxn],rk[maxn],tmp[maxn],buc[maxn],m,ht[maxn],st[maxn][19];
il vd Qsort(){
rep(i,0,m)buc[i]=0;
rep(i,1,n)buc[rk[tmp[i]]]++;
rep(i,1,m)buc[i]+=buc[i-1];
drep(i,n,1)sa[buc[rk[tmp[i]]]--]=tmp[i];
}
il bool cmp(int*h,int a,int b,int l){return h[a]==h[b]&&h[a+l]==h[b+l];}
il vd solve(){
m=tot;
rep(i,1,n)rk[i]=c[i],tmp[i]=i;
Qsort();
int p=0;
for(rg int l=1;p<n;l<<=1){
p=0;
rep(i,n-l+1,n)tmp[++p]=i;
rep(i,1,n)if(sa[i]>l)tmp[++p]=sa[i]-l;
Qsort();
rep(i,1,n)tmp[i]=rk[i];
p=rk[sa[1]]=1;
rep(i,2,n)
if(cmp(tmp,sa[i],sa[i-1],l))rk[sa[i]]=p;
else rk[sa[i]]=++p;
m=p;
}
p=0;
rep(i,1,n)sa[rk[i]]=i;
rep(i,1,n){
if(p)--p;
if(rk[i]==n)continue;
while(c[i+p]==c[sa[rk[i]+1]+p])++p;
ht[rk[i]]=st[rk[i]][0]=p;
}
int Log=log2(n);
rep(i,1,Log)drep(j,n-(1<<i)+1,1)st[j][i]=min(st[j][i-1],st[j+(1<<(i-1))][i-1]);
}
bool operator <(node AAA,node BBB){return rk[AAA.l]<rk[BBB.l];}
il int lcp(int a,int b){
a=rk[a],b=rk[b];
if(a==b)return n-a+1;
if(a>b)swap(a,b);--b;
int Log=log2(b-a+1);
return min(st[a][Log],st[b-(1<<Log)+1][Log]);
}
int main(){
freopen(Fname".in","r",stdin);
freopen(Fname".out","w",stdout);
n=gi();
rep(i,1,n)c[n-i+1]=data[n-i+1]=gi();c[n+1]=-23333333;
sort(data+1,data+1+n);
tot=unique(data+1,data+1+n)-data-1;
rep(i,1,n)c[i]=lower_bound(data+1,data+tot+1,c[i])-data;
solve();
puts("1"),s.insert(Make(n));
ll ht=0;
set<node>::iterator it,itl,itr;
drep(i,n-1,1){
it=s.insert(Make(i)).first;
itl=it,--itl;
itr=it,++itr;
if(it==s.begin())ht+=lcp(it->l,itr->l);
else if(itr==s.end())ht+=lcp(itl->l,it->l);
else ht+=lcp(it->l,itr->l)+lcp(itl->l,it->l)-lcp(itl->l,itr->l);
printf("%lld\n",(ll)(n-i+1)*(n-i+2)/2-ht);
}
return 0;
}
cogs2223 [SDOI2016 Round1] 生成魔咒的更多相关文章
- cogs2223. [SDOI2016 Round1] 生成魔咒(后缀数组 hash 二分 set
题意:对一个空串每次在后面加一个字符,问每加完一次得到的字符串有几个不同的子串. 思路:每个子串都是某个后缀的前缀,对于每个后缀求出他能贡献出之前没有出现过的前缀的个数,答案累加就行. 要求每个后缀的 ...
- cogs 2223. [SDOI2016 Round1] 生成魔咒
★★☆ 输入文件:menci_incantation.in 输出文件:menci_incantation.out 简单对比 时间限制:1 s 内存限制:128 MB [题目描述]魔咒串由许多魔咒字符组 ...
- liberOJ #2033. 「SDOI2016」生成魔咒 后缀数组
#2033. 「SDOI2016」生成魔咒 题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1 11.2 22 拼凑起来形成一个魔咒串 [1,2] [1, 2] ...
- 【BZOJ4516】【SDOI2016】生成魔咒 [SAM]
生成魔咒 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 魔咒串由许多魔咒字符组成,魔咒字符 ...
- 【LOJ】 #2033. 「SDOI2016」生成魔咒
题解 就是字符集较大需要离散化和建边表的后缀自动机水题 每次会加入i个新的串,其中重复的就是i的父亲节点所在节点的长度,减掉即可 代码 #include <iostream> #inclu ...
- BZOJ4516: [Sdoi2016]生成魔咒 后缀自动机
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #inclu ...
- BZOJ 4516: [Sdoi2016]生成魔咒 [后缀自动机]
4516: [Sdoi2016]生成魔咒 题意:询问一个字符串每个前缀有多少不同的子串 做了一下SDOI2016R1D2,题好水啊随便AK 强行开map上SAM 每个状态的贡献就是\(Max(s)-M ...
- BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay
BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔 ...
- P4070 [SDOI2016]生成魔咒
题目地址:P4070 [SDOI2016]生成魔咒 相信看到题目之后很多人跟我的思路是一样的-- 肯定要用 SA(P3809 [模板]后缀排序) 肯定要会求本质不同的子串个数(P2408 不同子串个数 ...
随机推荐
- 最大传输单元MTU
http://baike.baidu.com/link?url=mU41JFjZzOb3R5crQFCNdocT5ovAswcoIqL2A4U6O5Re_U0-HIYndHG0vSKwc6HbptvH ...
- luogu P1262 间谍网络
嘟嘟嘟 建图还是很明显的. 接着分两种情况: 1.图中不存在环:那么只要收买那些入度为0的点.如果这些点有的不能收买.就不能控制所有间谍. 2.图中存在环,那么对于这些在环中的点,我们只要收买数额最少 ...
- win10里如何在中文输入法里添加美式键盘
在控制面板打开“时钟.语言和区域”设置界面,选中“语言”设置 “语言”设置里点击“添加语言” 在添加语言设置里选择“英语”,并点击“打开”按钮,在“区域变量”设置页面里选择“英语(美国)” ,并点击 ...
- Spring(十一)之AOP
Spring 框架的一个关键组件是面向方面的编程(AOP)框架.面向方面的编程需要把程序逻辑分解成不同的部分称为所谓的关注点.跨一个应用程序的多个点的功能被称为横切关注点,这些横切关注点在概念上独立于 ...
- PAT——1024. 科学计数法
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式[+-][1-9]"."[0-9]+E[+-][0-9]+,即数字的整数部分只有1位,小数部分至少有1位 ...
- 【51nod 1685】 第K大区间2
题目描述: 定义一个长度为奇数的区间的值为其所包含的的元素的中位数.现给出n个数,求将所有长度为奇数的区间的值排序后,第K大的值为多少. 样例解释: [l,r]表示区间的值 [1]:3 [2]:1 [ ...
- loadrunner脚本中参数化和返回值输出log到外部文件
loadrunner脚本中参数化和返回值输出log到外部文件 很多时候,我们在做性能测试之前,需要造数据,但是使用的这些参数化数据和生成的返回数据在后面的测试都会用的,所以我们需要在造数据过程中,将参 ...
- mysql常见字符串处理函数
- react 配置开发环境
一:先自行下载安装node和npm 二:cnpm install create-react-app -g 三:create-react-app my-project 四:cd my-project ...
- java核心技术-多线程之基本使用
多线程程序好处就是可以提高cpu使用率和系统的性能.这里举个例子,民以食为天,咱们以餐馆为例(后面基本上都用餐馆作为对象),后面如果没有特殊说明均采用本节相关术语,围绕餐馆我们可以抽象出如下几个角色以 ...