洛谷P7361:拜神(SA、二分、主席树、启发式合并)

解析

很好的一道SA的题。(觉得完全可以评黑了啊qwq)
我一开始拿SAM和线段树硬做,不断修正最后发现自己无法在可接受复杂度内解决的问题,直接GG…
垃圾数据还骗到了50分
所以写一道题之前还是要先想仔细了,确定整个流程没有锅再写吧,尽量避免写一半发现不对再修正甚至直接假掉的情况,还能使实现时更加系统简洁。

考虑SA。
为什么搜SAM的tag结果全是拿SA做的啊。

答案显然具有单调性,考虑check二分的答案 LLL 是否合法。
合法的情况可以等价抽象为:区间内存在两个后缀 p,qp,qp,q,使得 lcp(p,q)≤Llcp(p,q)\le Llcp(p,q)L
用类似品酒大会的思路(这个思路似乎非常常见好用),把所有 hi≥Lh_i\ge LhiLi,i−1i,i-1i,i1 合并,最后就是看区间内是否有两个点在同一个集合内。

在线段树上存储每个结点左侧在同一集合内的结点最靠右的位置,问题转化为查询 [l,r−L+1][l,r-L+1][l,rL+1] 的最大值是否大于 LLL
这个线段树可以用主席树维护,每个并查集集合维护一个 set,启发式合并暴力查找前驱后缀即可。

时空复杂度 O(nlog2n)O(nlog^2n)O(nlog2n)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
const int N=1e5+100;
const int M=1e6+100;
const int mod=1e9;int n,m;
char s[N];int sa[N],rk[N],id[N],oldrk[N],cnt[N];
int h[N];
void SA(){int m=300;//printf("%s\n",s+1);for(int i=1;i<=n;i++) ++cnt[rk[i]=s[i]];for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];for(int i=n;i>=1;i--) sa[cnt[rk[i]]--]=i;for(int w=1;m!=n;w<<=1){int p=0;for(int i=n;i>n-w;i--) id[++p]=i;for(int i=1;i<=n;i++){if(sa[i]>w) id[++p]=sa[i]-w;}memset(cnt,0,sizeof(cnt));memcpy(oldrk,rk,sizeof(rk));for(int i=1;i<=n;i++) ++cnt[rk[id[i]]];for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];for(int i=n;i>=1;i--) sa[cnt[rk[id[i]]]--]=id[i];m=0;for(int i=1;i<=n;i++){if(oldrk[sa[i]]==oldrk[sa[i-1]]&&oldrk[sa[i]+w]==oldrk[sa[i-1]+w]) rk[sa[i]]=m;else rk[sa[i]]=++m;}}for(int i=1,y=0;i<=n;i++){if(y) --y;while(s[i+y]==s[sa[rk[i]-1]+y]) ++y;h[rk[i]]=y;}//for(int i=1;i<=n;i++) printf("i=%d %s sa=%d h=%d\n",i,s+sa[i],sa[i],h[i]);return;
}struct tree{int ls,rs,mx;
};
const int C=100;
struct Sefment_Tree{tree tr[N*C];int tot;#define mid ((l+r)>>1)inline int copy(int x){tr[++tot]=tr[x];assert(tot<N*C);return tot;}inline void pushup(int k){tr[k].mx=max(tr[tr[k].ls].mx,tr[tr[k].rs].mx);return;}int ask(int k,int l,int r,int x,int y){if(!k) return 0;if(x<=l&&r<=y) return tr[k].mx;int res=0;if(x<=mid) res=max(res,ask(tr[k].ls,l,mid,x,y));if(y>mid) res=max(res,ask(tr[k].rs,mid+1,r,x,y));return res;}void change(int &k,int l,int r,int p,int w){k=copy(k);if(l==r){tr[k].mx=max(tr[k].mx,w);return;}if(p<=mid) change(tr[k].ls,l,mid,p,w);else change(tr[k].rs,mid+1,r,p,w);pushup(k);}#undef mid
}t;
int rt[N];set<int>S[N];
set<int>::iterator it;
inline int Suf(int k,int w){it=S[k].lower_bound(w);return (it==S[k].end())?0:(*it);
}
inline int Pre(int k,int w){it=S[k].lower_bound(w);if(it==S[k].begin()) return 0;else{it--;return (*it);}
}
int fa[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int x,int y,int L){//printf("merge: %d %d L=%d\n",x,y,L);	x=find(x);y=find(y);if(S[x].size()>S[y].size()) swap(x,y);//printf("  x=%d y=%d\n",x,y);for(int now:S[x]){int pre=Pre(y,now),suf=Suf(y,now);if(pre) t.change(rt[L],1,n,now,pre);if(suf) t.change(rt[L],1,n,suf,now);//printf("  ins:now=%d pre=%d suf=%d\n",now,pre,suf);}for(int now:S[x]){S[y].insert(now);}S[x].clear();fa[x]=y;return;
}struct node{int h,id;bool operator < (const node o)const{return h>o.h;}
}p[N];signed main(){#ifndef ONLINE_JUDGE//freopen("a.in","w",stdin);//freopen("a.out","w",stdin);#endifn=read();m=read();//printf("%d\n",n);scanf(" %s",s+1);SA();int num(0);for(int i=1;i<=n;i++){fa[i]=i;S[i].insert(i);if(i>1) p[++num]=(node){h[i],i};}sort(p+1,p+1+num);int pl=1;for(int i=n;i>=0;i--){rt[i]=rt[i+1];while(pl<=num&&p[pl].h==i){if(p[pl].id>1){int x=sa[p[pl].id],y=sa[p[pl].id-1];merge(x,y,i);}++pl;}}for(int i=1;i<=m;i++){int l=read(),r=read(),st=0,ed=n;while(st<ed){int mid=(st+ed+1)>>1;if(t.ask(rt[mid],1,n,l,r-mid+1)>=l) st=mid;else ed=mid-1;}printf("%d\n",st);}return 0;
}
/*
8 1
aabaabba
4 5*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317092.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Doing Homework HDU - 1074

Doing Homework HDU - 1074 题意&#xff1a; 有n个任务&#xff0c;每个任务有一个截止时间&#xff0c;超过截止时间一天&#xff0c;要扣一个分。 求如何安排任务&#xff0c;使得扣的分数最少。 (1<n<15) 题解&#xff1a; n很小&#xff0c;可以往状压dp方向去想…

【学习笔记】浅谈广义矩阵乘法——动态DP

文章目录广义矩阵乘法动态DP例题&#xff1a;洛谷4719以下内容是本人做题经验&#xff0c;如有雷同&#xff0c;纯属抄袭&#xff1b;如有不对&#xff0c;纯属不懂&#xff0c;还请指正 广义矩阵乘法 众所周知&#xff0c;矩阵满足乘法交换律&#xff0c;前一个矩阵的列必须…

我们为什么要搞长沙.NET技术社区?

某种意义上讲&#xff0c;长沙和中国大部分内地城市一样&#xff0c;都是互联网时代的灯下黑。没有真正意义上的互联网公司&#xff0c;例如最近发布的中国互联网企业一百强中没有一家湖南或者长沙的公司就是明证。然而长沙并非没有互联网人&#xff0c;在麓谷几十万计的IT 从业…

洛谷P5212:SubString(SAM、LCT)

解析 所谓SAM套LCT&#xff0c;真的就只是SAM套LCT。。。 考试写起来应该有亿点点恶心 每次在SAM节点修改的时候在LCT对应位置修改即可。 注意&#xff01; 克隆节点之前需要先splay一下把所有标记接收。 没了。 #include<bits/stdc.h> using namespace std; #define…

在ASP.NET Core中使用EPPlus导入出Excel文件

这篇文章说明了如何使用EPPlus在ASP.NET Core中导入和导出.xls/.xlsx文件&#xff08;Excel&#xff09;。在考虑使用.NET处理excel时&#xff0c;我们总是寻找第三方库或组件。使用Open Office Xml格式&#xff08;xlsx&#xff09;读取和写入Excel 2007/2010文件的最流行的.n…

[kuangbin]专题12 基础DP

HDU 1024 Max Sum Plus Plus HDU 1029 Ignatius and the Princess IV HDU 1069 Monkey and Banana HDU 1074 Doing Homework HDU 1087 Super Jumping! Jumping! Jumping! HDU 1114 Piggy-Bank HDU 1176 免费馅饼 HDU 1260 Tickets HDU 1257 最少拦截系统 HDU 1160 FatMouse’s …

[2021-09-11 CQBZ/HSZX多校联考 T1] 茅山道术 (后缀和优化dp)

茅山道术descriptionsolutioncodedescription 题目描述 小七擅长茅山道术&#xff0c;有一天他发现了 n 个排成一行的宝石&#xff0c;其中第 i 个宝石 有一个颜色 ci 。 小七决定用茅山道术替换一些宝石&#xff0c;具体地&#xff0c;他每次施法可以选定两个满足 cl cr 的正…

洛谷P1484:种树(反悔贪心)

解析 反悔贪心好题。 我放弃wqs二分做法好吧。 要加强从边界和特殊情况入手思考问题的思想。 考虑选一个的时候&#xff0c;肯定是选最大值。 此时它两侧的值就不能选了。 那如果我后来不选这个最大值了&#xff0c;必然是我转而把它两侧的值都给选了&#xff0c;额外消耗一…

月旦评 之 DevOps招贤令2019 - 没有人比我们更懂DevOps

公元164-182年间&#xff0c;汝南平舆的许氏兄弟于每月初一品评人物&#xff0c;褒贬时政&#xff0c;被称为“月旦评”。所谓“子治世之能臣&#xff0c;乱世之奸雄也”这句许邵评价曹操的话也是来自于“月旦评”&#xff1b;时间一下子来到了2019年&#xff0c;DevOps招贤令再…

HDU - 2204 Eddy‘s爱好(尚未完全解决)

HDU - 2204 Eddy’s爱好 题意&#xff1a; 给你一个正整数N&#xff0c;确定在1到N之间有多少个可以表示成M^K&#xff08;K>1)的数 题解&#xff1a; 参考题解&#xff1a; 我们先举例找找规律 1~10以内2的次方有多少个&#xff1f;有121,224,329,一共三个&#xff0c;…

[2020-09-11 CQBZ/HSZX多校联测 T2] 泰拳警告(组合数+数学期望)

泰拳警告descriptionsolutioncodedescription 题目描述 小七擅长泰拳&#xff0c;某天他打算与小枣切磋拳技&#xff0c;一共需要进行 n 次比赛。 由于双方拳技难分上下&#xff0c;每场比赛小七获胜或落败的概率都是 1/p2 &#xff0c;平局的概率是 p/p2 若最后小七获胜场数大…

模板:wqs二分

所谓wqs&#xff0c;就是windwhisper说&#xff1a;“qs” &#xff08;逃&#xff09; 解析 很神奇的科技。 四两拨千斤的解决一些本来可能不太好解决的问题。 经典模型&#xff1a;有若干个物品&#xff0c;要求选出 mmm 个&#xff0c;选的时候带有限制&#xff0c;求最优…

EF Core中避免贫血模型的三种行之有效的方法(翻译)

[Paul Hiles: 3 ways to avoid an anemic domain model in EF Core &#xff1a;https://www.devtrends.co.uk/blog/3-ways-to-avoid-an-anemic-domain-model-in-ef-core]1.引言在使用ORM中&#xff08;比如Entity Framework&#xff09;贫血领域模型十分常见 。本篇文章将先探…

[ONTAK2010] Peaks加强版 (kruskal重构树+主席树+倍增)

Peaksdescriptionsolutioncodedescription 在Bytemountains有N座山峰&#xff0c;每座山峰有他的高度h_i 有些山峰之间有双向道路相连&#xff0c;共M条路径&#xff0c;每条路径有一个困难值&#xff0c;这个值越大表示越难走 现在有Q组询问&#xff0c;每组询问询问从点v开…

洛谷P2754:[CTSC1999]家园 / 星际转移问题(网络流)

解析 容易想到对每个时间的空间站都建一个点。 然后发现循环问题很难搞。 然后我就一直想从 lcm 下文章&#xff0c;结果 lcm 可以到3e5&#xff0c;于是就寄了… qwq 注意到本题的数据范围极小&#xff01; 那个3e5云云是不可能跑出来的&#xff0c;事实上&#xff0c;答案不…

Saving Beans HDU - 3037(卢卡斯定理)

Saving Beans HDU - 3037&#xff08;卢卡斯定理&#xff09; 题意&#xff1a; 他们想知道有多少种方法可以在n树中保存不超过m个bean&#xff08;它们是相同的&#xff09;。 现在他们求助于你&#xff0c;你应该给他们答案。 结果可能非常巨大; 你应该输出模p的结果&…

我们为什么要搞长沙.NET技术社区(三)

我们为什么要搞长沙.NET技术社区&#xff08;三&#xff09; 小饭局搞事情先从饭局开始是中华民族的优良传统。昨天晚餐时间&#xff0c;长沙 .net 技术社区的主要发起人员进行了一番小聚&#xff0c;同时也作为一个非正式会议&#xff0c;对社区发展进行了探讨。从介绍自己对于…

BZOJ4504. K个串(主席树+优先队列)

4504. K个串descriptionsolutioncodedescription 兔子们在玩k个串的游戏。首先&#xff0c;它们拿出了一个长度为n的数字序列&#xff0c;选出其中的一 个连续子串&#xff0c;然后统计其子串中所有数字之和&#xff08;注意这里重复出现的数字只被统计一次&#xff09;。 兔…

【招聘(北京)】北森测评招聘 .NET 架构师、高级工程师

工作职责公司核心产品的迭代需求分析设计开发。公司核心产品的线上维护和性能调优。对初中级技术人员培养和质量把关。编写软件设计和技术文档。任职资格为人正直、诚信、责任心强&#xff0c;能承受较大工作压力。强烈的目标导向意识&#xff0c;逻辑思维清晰&#xff0c;执行…

网络流模型与技巧总结

文章目录前言常见基本模型最大匹配、最小点覆盖和最大独立集构造最小点覆盖最大点权匹配最小路径覆盖不可重覆盖可重覆盖最大权闭合子图建图技巧利用拆点进行限流利用断边表示决策利用虚点表示组合关系链状模型用链表示时间轴用链表示偏序关系形式的选取限制通过拆点描述先后顺…