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
" : "No
");
58     }
59     return 0;
60 }
View Code
原文地址:https://www.cnblogs.com/jimzeng/p/bzoj3207.html