BZOJ3207 花神的嘲讽计划Ⅰ
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3207
Description
背景
花神是神,一大癖好就是嘲讽大J,举例如下:
“哎你傻不傻的!【hqz:大笨J】”
“这道题又被J屎过了!!”
“J这程序怎么跑这么快!J要逆袭了!”
……
描述
这一天DJ在给吾等众蒟蒻讲题,花神在一边做题无聊,就跑到了一边跟吾等众蒟蒻一起听。以下是部分摘录:
1.
“J你在讲什么!”
“我在讲XXX!”
“哎你傻不傻的!这么麻烦,直接XXX再XXX就好了!”
“……”
2.
“J你XXX讲过了没?”
“……”
“那个都不讲你就讲这个了?哎你傻不傻的!”
“……”
DJ对这种情景表示非常无语,每每出现这种情况,DJ都是非常尴尬的。
经过众蒟蒻研究,DJ在讲课之前会有一个长度为N方案,我们可以把它看作一个数列;
同样,花神在听课之前也会有一个嘲讽方案,有M个,每次会在x到y的这段时间开始嘲讽,为了减少题目难度,每次嘲讽方案的长度是一定的,为K。
花神嘲讽DJ让DJ尴尬需要的条件:
在x~y的时间内DJ没有讲到花神的嘲讽方案,即J的讲课方案中的x~y没有花神的嘲讽方案【这样花神会嘲讽J不会所以不讲】。
经过众蒟蒻努力,在一次讲课之前得到了花神嘲讽的各次方案,DJ得知了这个消息以后欣喜不已,DJ想知道花神的每次嘲讽是否会让DJ尴尬【说不出话来】。
Input
第1行3个数N,M,K;
第2行N个数,意义如上;
第3行到第3+M-1行,每行K+2个数,前两个数为x,y,然后K个数,意义如上;
Output
对于每一个嘲讽做出一个回答会尴尬输出‘Yes’,否则输出‘No’
Hash + 可持久化线段树,并不用离散化
将原数字串hash后扔进可持久化线段树,将询问hash后查询
注意的问题:空间开40倍否则RE;mid要写成
ull mid = (l >> 1) + (r >> 1);
if ((l & 1) && (r & 1)) mid++;
以防止爆unsigned long long。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #define rep(i,l,r) for(int i=l; i<=r; i++) 6 #define clr(x,y) memset(x,y,sizeof(x)) 7 #define travel(x) for(Edge *p=last[x]; p; p=p->pre) 8 using namespace std; 9 typedef unsigned long long ull; 10 const ull INF = 18446744073709551615UL; 11 const int maxn = 200010; 12 inline int read(){ 13 int ans = 0, f = 1; 14 char c = getchar(); 15 for(; !isdigit(c); c = getchar()) 16 if (c == '-') f = -1; 17 for(; isdigit(c); c = getchar()) 18 ans = ans * 10 + c - '0'; 19 return ans * f; 20 } 21 int n,m,k,l,r,cnt=0,rt[maxn],a[maxn],tmp[maxn],son[maxn*40][2],sum[maxn*40]; 22 ull h[maxn]; 23 void insert(ull l,ull r,int x,int &y,ull v){ 24 y = ++cnt; 25 sum[y] = sum[x] + 1; 26 if (l == r) return; 27 son[y][0] = son[x][0]; son[y][1] = son[x][1]; 28 ull mid = (l >> 1) + (r >> 1); 29 if ((l & 1) && (r & 1)) mid++; 30 int d = v > mid; 31 if (d) insert(mid+1,r,son[x][1],son[y][1],v); 32 else insert(l,mid,son[x][0],son[y][0],v); 33 } 34 bool query(int x,int y,ull v){ 35 ull l = 0, r = INF; 36 while (l < r){ 37 ull mid = (l >> 1) + (r >> 1); 38 if ((l & 1) && (r & 1)) mid++; 39 int d; 40 if (v > mid) l = mid + 1, d = 1; 41 else r = mid, d = 0; 42 x = son[x][d]; y = son[y][d]; 43 } 44 return sum[y] - sum[x] == 0; 45 } 46 int main(){ 47 n = read(); m = read(); k = read(); 48 rep(i,1,n) a[i] = read(); 49 rep(i,1,n) h[i] = h[i-1] * 107 + a[i]; 50 ull p = 1; rep(i,1,k) p *= 107; 51 rep(i,k,n) insert(0,INF,rt[i-1],rt[i],h[i] - h[i-k] * p); 52 rep(i,1,m){ 53 l = read(); r = read(); 54 rep(j,1,k) tmp[j] = read(); 55 ull htmp = 0; 56 rep(j,1,k) htmp = htmp * 107 + tmp[j]; 57 printf(query(rt[l+k-2],rt[r],htmp) ? "Yes\n" : "No\n"); 58 } 59 return 0; 60 }