bzoj3207--Hash+主席树

题目大意:

给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现。

思路:
把所有连续的k个数字hash一下,然后扔进主席树,询问时在主席树中查询就可以了。

注意(坑)点:
1、hash值要用unsigned long long存

2、如果直接求l+r>>1会爆,所以要改成(l>>1)+(r>>1)+(l&r&1)

3、Yes和No是反的。。。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<limits.h>
 6 using namespace std;
 7 #define N 100001
 8 #define M ULLONG_MAX
 9 #define ll unsigned long long
10 inline char Nc(){
11     static char buf[100000],*p1=buf,*p2=buf;
12     if(p1==p2){
13         p2=(p1=buf)+fread(buf,1,100000,stdin);
14         if(p1==p2)return EOF;
15     }
16     return *p1++;
17 }
18 inline void Read(int& x){
19     char c=Nc(),b=1;
20     for(;c<‘0‘||c>‘9‘;c=Nc())if(c==‘-‘)b=-1;
21     for(x=0;c>=‘0‘&&c<=‘9‘;x=(x<<3)+(x<<1)+c-48,c=Nc());x*=b;
22 }
23 struct Gj{
24     int l,r,w;
25 }c[N*80];
26 int Num,i,j,k,n,m,Rt[N],x,y,z,a[N];
27 ll Hash[N],w,h;
28 inline void Update(int& Node,ll l,ll r,ll x){
29     c[++Num]=c[Node];Node=Num;
30     c[Node].w++;
31     if(l==r)return;
32     ll Mid=(l>>1)+(r>>1)+(l&r&1);
33     if(x<=Mid)Update(c[Node].l,l,Mid,x);else Update(c[Node].r,Mid+1,r,x);
34 }
35 inline bool Query(int x,int y,ll l,ll r,ll h){
36     if(c[y].w-c[x].w==0)return 0;
37     if(l==r)return 1;
38     ll Mid=(l>>1)+(r>>1)+(l&r&1);
39     if(h<=Mid)return Query(c[x].l,c[y].l,l,Mid,h);else return Query(c[x].r,c[y].r,Mid+1,r,h);
40 }
41 int main()
42 {
43     Read(n);Read(m);Read(k);
44     for(i=1;i<=n;i++)Read(a[i]);
45     for(i=1;i<=n;i++)Hash[i]=Hash[i-1]*99997+a[i];
46     for(w=1,i=1;i<=k;i++)w*=99997;
47     for(i=k;i<=n;i++){
48         Rt[i]=Rt[i-1];
49         Update(Rt[i],1,M,Hash[i]-Hash[i-k]*w);
50     }
51     for(i=1;i<=m;i++){
52         Read(x);Read(y);
53         for(h=0,j=1;j<=k;j++)Read(z),h=h*99997+z;
54         if(y-x+1>=k&&Query(Rt[x+k-2],Rt[y],1,M,h))puts("No");else puts("Yes");
55     }
56     return 0;
57 }

bzoj3207

时间: 2024-07-28 23:51:25

bzoj3207--Hash+主席树的相关文章

【BZOJ3207】花神的嘲讽计划Ⅰ Hash+主席树

[BZOJ3207]花神的嘲讽计划Ⅰ Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程序怎么跑这么快!J要逆袭了!” …… 描述 这一天DJ在给吾等众蒟蒻讲题,花神在一边做题无聊,就跑到了一边跟吾等众蒟蒻一起听.以下是部分摘录: 1. “J你在讲什么!” “我在讲XXX!” “哎你傻不傻的!这么麻烦,直接XXX再XXX就好了!” “……” 2. “J你XXX讲过了没?” “……” “那个都不讲你就

BZOJ_3207_花神的嘲讽计划1_(Hash+主席树)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3207 给出一个长度为\(n\)的串,以及\(m\)个长度为\(k\)的串,求每个长度为\(k\)的串在原串\([x,y]\)区间是否出现过. 分析 这道题要求对比长度为\(k\)的串,于是我们把这些串的Hash值都算出来,问题就转化成了求\([x,y]\)的区间中是否出现过某Hash值. 求区间中某一个值出现了多少次,可以用主席树. p.s. 1.学习了主席树指针的写法,比数组慢好多啊...

Codeforces 464E #265 (Div. 1) E. The Classic Problem 主席树+Hash

E. The Classic Problem http://codeforces.com/problemset/problem/464/E 题意:给你一张无向带权图,求S-T的最短路,并输出路径.边权为2^xi.xi≤105,n≤105,m≤105. 想法:边权太大了,可以用数组按二进制存下来.带高精度跑太费事了. 观察一下,这里距离的更新:c=(a,b),用dis[a]更新dis[b] ①dis[b][c]=0,直接赋为1.只有一个数字改变. ②dis[b][c]=1,需要进位.考虑极端情况数

[BZOJ3207] 花神的嘲讽计划Ⅰ (主席树)

Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程序怎么跑这么快!J要逆袭了!” …… 描述 这一天DJ在给吾等众蒟蒻讲题,花神在一边做题无聊,就跑到了一边跟吾等众蒟蒻一起听.以下是部分摘录: 1. “J你在讲什么!” “我在讲XXX!” “哎你傻不傻的!这么麻烦,直接XXX再XXX就好了!” “……” 2. “J你XXX讲过了没?” “……” “那个都不讲你就讲这个了?哎你傻不傻的!” “……”

【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树

这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,Lca只是他的一种应用,他可以搞各种树上问题,树上倍增一般都会用到f数组. |||.我们跑出来dfs序就能在他的上面进行主席树了. IV.别忘了离散. V.他可能不连通,我一开始想到了,但是我觉得出题人可能会是好(S)人(B),但是...... #include <cstdio> #include

[主席树]ZOJ3888 Twelves Monkeys

题意:有n年,其中m年可以乘时光机回到过去,q个询问 下面m行,x,y 表示可以在y年穿越回x年, 保证y>x 下面q个询问, 每个询问有个年份k 问的是k年前面 有多少年可以通过一种以上($\ge 2$)方法穿越回去的, 其中时光机只能用一次 比如案例 9 3 3 9 1 6 1 4 1 6 7 2 如图 对于询问 6这一年:1.穿越回第1年  2.等时间过呀过呀过到第9年,再穿越回第1年 那么第1年就有两种方法可以穿越回去, 同理, 2.3.4年也有同样两种方法(回到1再等时间过呀过 过到2

主席树

#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <cstdlib> #define maxn 100005 using namespace std; int b[maxn],t[maxn],n,m,size,v[maxn],tot

主席树复习

T1 [CQOI2015]任务查询系统 n个任务,每个有运行的时间段和优先级,询问某一时刻,优先级最小的个任务的优先级之和 初做:  2017.2.4   http://www.cnblogs.com/TheRoadToTheGold/p/6366165.html 好像是做了一晚上来 现在:2017.3.27   14:17——15:56 用了接近2个小时做了一道以前做过的题,还是弱啊~~~~(>_<)~~~~ difference: 主席树维护的东西不同,以前直接存储优先级之和,现在存储的是

BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca

2588: Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文. Input 第一行两个整数N,M. 第二行有N个整数,其中第i个整数表示点i的权值. 后面N-1行每行两个整数(x,y),表示点x到点y有一条边. 最后M行每行两个整数(u,v,k),表示一组询问.