BZOJ-3207 花神的嘲讽计划Ⅰ ,hash+可持久化线段树
来源:互联网 发布:写小说软件 编辑:程序博客网 时间:2024/05/29 18:34
花神的嘲讽计划Ⅰ
昨天才看懂的可持久化线段树,被这题坑了一天。题意:相当于给你长度为n的主串,M次查询,每次查询一个区间中长度为k的子串是否出现过。
因为长度k是确定的,我们把原来的数列所有长度为k的子序列hash然后用可持久化线段树保存起来,用大佬的话讲就是预处理出来的hash值扔进主席树里,查询即可。大致就是这样,考虑到数据范围,我把所有的hash值再进行了hash一波,这样我们只需插入权值即可,然后查询把k个数的hash值lower_bound一下,查找对应区间中的这个位置上的数是否出现过。
坑点:
hash需要用unsigned long long ,自动取余。
至今不明白为什么用fread快读不行,而普通快读可以,普通快读是2900ms左右,用scanf注意用llu输入,不能用I64u,血的教训,4500ms左右。
其余的就是可持久线段树了,还是不习惯用主席树,虽然听起来高大上,不过可持久数据结构还是主流。
const ul B=107;const ul BB=10;const int N=2e5+10;int tot,n,m,nn,k;int sum[N],root[N*40],lc[N*40],rc[N*40];ul a[N],ha[N],p[N];inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline int sc(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}void init_hash(){ tot=0; for(int i=1;i<=n;i++) ha[i]=a[i]; sort(ha+1,ha+n+1); nn=unique(ha+1,ha+n+1)-ha-1;}int build(int l,int r){ int id=tot++; sum[id]=0; if(l!=r) { int mid=(l+r)/2; lc[id]=build(l,mid); rc[id]=build(mid+1,r); } return id;}int update(int id,int pos){ int newid=tot++,tmp=newid; sum[newid]=sum[id]+1; int l=1,r=nn; while(l<r) { int mid=(l+r)/2; if(pos<=mid) { lc[newid]=tot++;rc[newid]=rc[id]; newid=lc[newid],id=lc[id]; r=mid; } else { rc[newid]=tot++;lc[newid]=lc[id]; newid=rc[newid],id=rc[id]; l=mid+1; } sum[newid]=sum[id]+1; } return tmp;}int find(int l,int r,int pos){ int L=1,R=nn; while(L<R) { int mid=(L+R)/2; if(pos<=mid) { l=lc[l]; r=lc[r]; R=mid; } else { r=rc[r]; l=rc[l]; L=mid+1; } } if(sum[r]-sum[l]) return 1; return 0;}int main(){ while(~scanf("%d%d%d",&n,&m,&k)) { p[0]=1; ha[0]=0; for(int i=1;i<=k;i++) p[i]=p[i-1]*B; for(int i=1;i<=n;i++) { a[i]=sc(); ha[i]=ha[i-1]*B+a[i]; if(i>=k) a[i]=ha[i]-ha[i-k]*p[k]; else a[i]=ha[i]; } init_hash(); root[0]=build(1,nn); for(int i=1;i<=n;i++) { int pos=lower_bound(ha+1,ha+nn+1,a[i])-ha; root[i]=update(root[i-1],pos); } while(m--) { int l,r; ul x,tmp=0; scanf("%d%d",&l,&r); for(int i=1;i<=k;i++) { x=sc(); tmp=tmp*B+x; } int pos=lower_bound(ha+1,ha+1+nn,tmp)-ha; if(ha[pos]==tmp&&find(root[l+k-2],root[r],pos)) puts("No"); else puts("Yes"); } } return 0;}
阅读全文
0 0
- BZOJ 3207 花神的嘲讽计划Ⅰ Hash+可持久化线段树
- 【BZOJ 3207】花神的嘲讽计划Ⅰ(Hash + 可持久化线段树)
- BZOJ-3207 花神的嘲讽计划Ⅰ ,hash+可持久化线段树
- BZOJ 3207 花神的嘲讽计划I Hash+可持久化线段树/划分树
- BZOJ 3207 花神的嘲讽计划Ⅰ 可持久化线段树
- 【BZOJ3207】花神的嘲讽计划Ⅰ hash+可持久化线段树
- [BZOJ3207]花神的嘲讽计划Ⅰ(hash+可持久化线段树)
- bzoj 3207 花神的嘲讽计划Ⅰ hash 莫队
- BZOJ 3207 花神的嘲讽计划Ⅰ主席树+Hash
- BZOJ 3207: 花神的嘲讽计划Ⅰ|莫队|主席树|hash
- BZOJ 3207: 花神的嘲讽计划Ⅰ Hash,预处理或者在线主席树
- [BZOJ]3207: 花神的嘲讽计划Ⅰ 主席树+hash
- 3207: 花神的嘲讽计划Ⅰ 主席树+hash
- 【主席树】BZOJ 3207 花神的嘲讽计划Ⅰ
- bzoj 3207 花神的嘲讽计划Ⅰ 主席树
- [BZOJ3207][花神的嘲讽计划Ⅰ][主席树+Hash]
- bzoj-3207 花神的嘲讽计划Ⅰ
- BZOJ 3207 花神的嘲讽计划Ⅰ 题解&代码
- Html文本的解析库BeautifulSoup
- angular.js 表单验证
- 路由大项目
- @ResponseBody 和 @RequestBody 注解的区别
- 修改sql数据库显示远程调用失败
- BZOJ-3207 花神的嘲讽计划Ⅰ ,hash+可持久化线段树
- 小白跟老司机学网站搭建
- python 代码优化
- Git 版本控制(一)
- 路由界面
- AngularJS实现对用户信息的增删改查
- 童年回忆
- SpringMVC和struts,当然选前者了,后者恶心了
- dlib 15 dlib自带demo 基于DNN的车辆检测