后缀自动机求endpos集大小
#include<bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define LNF 0x3f3f3f3f3f3f3f3f
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pqueue priority_queue
#define NEW(a,b) memset(a,b,sizeof(a))
const double pi=4.0*atan(1.0);
const double e=exp(1.0);
const int maxn=4e5+;
typedef long long LL;
typedef unsigned long long ULL;
const LL mod=1e9+;
const ULL base=1e7+;
const int maxp=+;
using namespace std;
struct Suffix_Node{
int ch[maxp],par,len,jg;
LL dd[];
void init(){
NEW(ch,);
par=len=;
}
};
int num[maxn];
int la[maxn],ra[maxn];
int st[maxn];
int n,k;
ULL ans[maxn];
pair<ULL,int> w[maxn];
class Suffix_Automation{
private:
Suffix_Node s[maxn];
int cur,las,siz,crp,dx;
vector<int> gg[maxn];
struct node{
int to,nxt;
}g[maxn];
int cnt,head[maxn],pk[maxn];
public:
Suffix_Automation():las(),cur(),siz(),crp(){}
const void init(){
for(int i=;i<=siz;i++) {
pk[i]=;s[i].init();
for(int j=;j<=;j++) s[i].dd[j]=;
gg[i].clear();
ans[i]=;
for(int j=;j<;j++){
f[i][j]=;
}
}
las=cur=siz=crp=;
cnt=;
head[]=head[]=-;
dx=;
}
const int match(const char c)const{
return s[crp].ch[c-'a'];
}
const void withdraw(const int len){
while(crp!=&&s[s[crp].par].len>=len) crp=s[crp].par;
if(crp==) crp=;
}
const void Transfer(const int len,const char c){
crp=s[crp].ch[c-'a'];
if(crp==) crp=;
withdraw(len);
}
const void ex_tend(const char c){
int x=c-'a';
cur=++siz;
head[siz]=-;
s[cur].len =s[las].len+;
s[cur].jg=;
while(las!=&&!s[las].ch[x])
s[las].ch[x]=cur,las=s[las].par;
if(las==) s[cur].par=;
else{
int q,nq;
q=s[las].ch[x];
if(s[q].len==s[las].len+)
s[cur].par=q;
else{
nq=++siz;
head[siz]=-;
s[nq]=s[q],s[nq].len=s[las].len+;
s[nq].jg=;
s[cur].par=s[q].par=nq;
while(las!=&&s[las].ch[x]==q)
s[las].ch[x]=nq,las=s[las].par;
}
}
las=cur;
}
void dfs(int u){
if(f[u][]) return ;
add(s[u].par,u);
if(s[u].par!=){
dfs(s[u].par);
}
f[u][]=s[u].par;
}
void solve(){
for(int i=;i<=siz;i++){
if(!f[i][]){
dfs(i);
}
}
for(int j=;j<;j++){
for(int i=;i<=siz;i++){
f[i][j]=f[f[i][j-]][j-];
}
}
}
void add(int x,int y){
g[cnt].to=y;
g[cnt].nxt=head[x];
head[x]=cnt++;
}
int f[maxn][];
int d[maxn];
int fid(int u,int le){
int y;
for(int j=;j>=;j--){
y=f[u][j];
if(y!=&&s[y].len>=le){
u=y;
}
}
return u;
}
void dfs2(int u,int fa){
d[u]=d[fa]+;
la[u]=dx+;
if(pk[u]!=){
dx++;
num[dx]=pk[u];
}
for(int i=head[u];i!=-;i=g[i].nxt){
if(g[i].to!=fa){
dfs2(g[i].to,u);
s[u].jg+=s[g[i].to].jg;
}
}
ra[u]=dx;
gg[s[u].jg].push_back(u);
}
int get_dx(){
return dx;
}
void ins(int x){
pk[crp]=x;
st[x]=crp;
}
void sss(){
for(int i=n;i>=;i--){
for(int j=;j<gg[w[i].se].size();j++){
int y=gg[w[i].se][j];
while(y)
{
LL er=w[i].fi,flag=;
for(int j=;j>=;j--)
{
if(!(er>>j)) continue;
if(!s[y].dd[j]) {s[y].dd[j]=er;flag=;break;}
er^=s[y].dd[j];
}
if(!flag) break;
ans[y]+=w[i].fi;y=s[y].par;
}
} }
} }SAM;
char ss[maxn];
int main(){
int t;
scanf("%d",&t);
int x,y,z;
int ai;
int gh;
while(t--){
SAM.init();
scanf("%d",&n);
scanf("%s",ss);
for(int i=;i<=n;i++){
scanf("%llu",&w[i].fi);
w[i].se=i;
}
sort(w+,w++n);
for(int i=;ss[i];i++){
SAM.ex_tend(ss[i]);
}
SAM.solve();
for(int i=;ss[i];i++){
SAM.Transfer(i+,ss[i]);
SAM.ins(i+);
}
SAM.dfs2(,);
scanf("%d",&k);
int g=SAM.get_dx();
SAM.sss();
while(k--){
scanf("%d%d",&x,&y);
x=y-x+;
z=SAM.fid(st[y],x);
printf("%llu\n",ans[z]);
}
}
}
http://acm.hdu.edu.cn/showproblem.php?pid=6694
后缀自动机求endpos集大小的更多相关文章
- 后缀自动机求字典序第k小的串——p3975
又领悟到了一点新的东西,后缀自动机其实可以分为两个数据结构,一个是后缀树,还有一个是自动机 后缀树用来划分endpos集合,并且维护后缀之间的关系,此时每个结点代表的是一些后缀相同且长度连续的子串 自 ...
- SETI ACdream - 1430 后缀自动机求不相交子串
http://blog.csdn.net/gatevin/article/details/45875343 题目是求不重叠的不同子串个数 一般来说, endpos集合包含了子串结尾位置,结尾在&quo ...
- 洛谷P4248 [AHOI2013]差异(后缀自动机求lcp之和)
题目见此 题解:首先所有后缀都在最后一个np节点,然后他们都是从1号点出发沿一些字符边到达这个点的,所以下文称1号点为根节点,我们思考一下什么时候会产生lcp,显然是当他们从根节点开始一直跳相同节点的 ...
- Alice's Classified Message HDU - 5558 后缀自动机求某个后缀出现的最早位置
题意: 给定一个长度不超过 10W 的只包含小写字母的字符串,从下标 0 到 n−1.从下标 0 开始操作, 每次对于下标 pos查找下标 pos 开始的子串中最长的在其他地方出现过的长度,其他出现的 ...
- str2int HDU - 4436 后缀自动机求子串信息
题意: 给出 n 个串,求出这 n 个串所有子串代表的数字的和. 题解; 首先可以把这些串构建后缀自动机(sam.last=1就好了), 因为后缀自动机上从 root走到的任意节点都是一个子串,所有可 ...
- BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串
http://www.lydsy.com/JudgeOnline/problem.php?id=3998 后缀自动机应用的一个模板?需要对len进行一个排序之后再统计每个出现的数量,维护的是以该字符串 ...
- CodeForces-204E:Little Elephant and Strings (广义后缀自动机求出现次数)
The Little Elephant loves strings very much. He has an array a from n strings, consisting of lowerca ...
- 洛谷 P1368 工艺 后缀自动机 求最小表示
后缀自动机沙茶题 将字符串复制一次,建立后缀自动机. 在后缀自动机上贪心走 $n$ 次即可. Code: #include <cstdio> #include <algorithm& ...
- HDU 4641 K-string 后缀自动机 并查集
http://acm.hdu.edu.cn/showproblem.php?pid=4641 https://blog.csdn.net/asdfgh0308/article/details/4096 ...
随机推荐
- WUSTOJ 1246: 字符串排序(Java)
1246: 字符串排序 题目 输入n(n<100)个字符串,每个字符串长度不超过1000,将他们按字典顺序输出.更过内容点击标题. 分析 Java中的ArrayList()可以比较方便的 ...
- QLineEdit的信号函数
QLineEdit一共有6个信号函数,并不多,很好理解. ·void cursorPositionChanged( intold, intnew ) 当鼠标移动时发出此信号,old为先前的位置,new ...
- 数据库SQL语句大全——最常用的SQL语句
检索数据: 检索单个列: SELECT pname FROM product 检索多个列: SELECT pname,market_price,is_hot FROM product 检索所有列: S ...
- RabbitMq的环境安装
1.如图第一个是erlang语言的安装包,第二个是rabbitmq的安装包. 2.配置erlang语言环境,因为rabbitmq由erlang语言编写的,所以需要配置erlng语言环境. erlang ...
- PHP对程序员的要求更高
我这个文章标题可不是和大家开玩笑的哦 首先, 大家都知道, PHP也是一种编译型脚本语言, 和其他的预编译型语言不同, 它不是编译成中间代码, 然后发布.. 而是每次运行都需要编译.. 为此, 也 ...
- SQL Server系统函数:类型转换函数
原文:SQL Server系统函数:类型转换函数 1.基本的转化 SELECT CAST(2008 as varchar(4)) + ' year!' SELECT CONVERT(varchar(4 ...
- Snort Inline IPS Mode
Snort Inline IPS Mode https://forum.netgate.com/topic/143812/snort-package-4-0-inline-ips-mode-intro ...
- 货币转换B
描述 人民币和美元是世界上通用的两种货币之一,写一个程序进行货币间币值转换,其中: ...
- 自定义centos
目录 自定义centos 1. 为什么要自定义centos 2. 自定义centos步骤 自定义centos 1. 为什么要自定义centos 在使用官网的 centos镜像,只有200m,很小,但是 ...
- Microsoft 中间语言