您的位置:首页 > 其它

BZOJ 3207: 花神的嘲讽计划Ⅰ( hash + 可持久化线段树 )

2015-12-20 10:41 495 查看


O(NK)暴力搞出所有子串的哈希值, 然后就对哈希值离散化建权值线段树, 就是主席树的经典做法了.总时间复杂度O(NK+(N+Q)logN)

--------------------------------------------------------------------------

#include<cstdio>#include<algorithm>#include<cstring>#include<cctype>using namespace std;typedef unsigned long long ull;const int maxn = 100009;const ull P = 1000000007ULL;inline int read() { char c = getchar(); int ret = 0; for(; !isdigit(c); c = getchar()); for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0'; return ret;}int seq[maxn], r[maxn];int N, Q, K, n;ull H[maxn], Hash[maxn];void Init() { N = read(); Q = read(); K = read(); for(int i = 1; i <= N; i++) seq[i] = read(); n = N - K + 1; for(int i = 1; i <= n; i++) { H[i] = 0; for(int j = 0; j < K; j++) (H[i] *= P) += seq[i + j]; Hash[i] = H[i]; } sort(H + 1, H + n + 1); for(int i = 1; i <= n; i++) r[i] = lower_bound(H + 1, H + n + 1, Hash[i]) - H; }struct Node { Node *l, *r; int cnt;} pool[5000000], *pt, *Root[maxn], *Null;void Init_sgt() { pt = pool; Null = pt++; Null->l = Null->r = Null;}int Val;Node* Modify(Node* t, int l, int r) { Node* h = pt++; if(l == r) h->cnt = t->cnt + 1; else { int m = (l + r) >> 1; if(Val <= m) { h->l = Modify(t->l, l, m); h->r = t->r; } else { h->l = t->l; h->r = Modify(t->r, m + 1, r); } } return h;}int Query(Node* t, int l, int r) { if(l == r) return t->cnt; int m = (l + r) >> 1; if(Val <= m) return Query(t->l, l, m); return Query(t->r, m + 1, r);}void Solve() { Init_sgt(); Root[0] = Null; for(int i = 1; i <= n; i++) { Val = r[i]; Root[i] = Modify(Root[i - 1], 1, n); } while(Q--) { int l = read(), r = read() - K + 1; ull hash_val = 0; for(int i = 0; i < K; i++) (hash_val *= P) += read(); Val = lower_bound(H + 1, H + n + 1, hash_val) - H; if(l > r || H[Val] != hash_val) { puts("Yes"); continue; } puts(Query(Root[r], 1, n) > Query(Root[l - 1], 1, n) ? "No" : "Yes"); } }int main() { Init(); Solve(); return 0;}--------------------------------------------------------------------------

3207: 花神的嘲讽计划Ⅰ

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1132 Solved: 412
[Submit][Status][Discuss]

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’

Sample Input

8 5 3
1 2 3 4 5 6 7 8
2 5 2 3 4
1 8 3 2 1
5 7 4 5 6
2 5 1 2 3
1 7 3 4 5

Sample Output

No
Yes
Yes
Yes
No

HINT

题中所有数据不超过2*10^9;保证方案序列的每个数字<=N
2~5中有2 3 4的方案,输出No,表示DJ不会尴尬
1~8中没有3 2 1的方案,输出Yes,表示DJ会尴尬
5~7中没有4 5 6的方案,输出Yes,表示DJ会尴尬
2~5中没有1 2 3的方案,输出Yes,表示DJ会尴尬
1~7中有3 4 5的方案,输出No,表示DJ不会尴尬

Source

原创 Memphis
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: