这道题要看出来这个做法还是比较容易说一下细节
1.因为要用hash的区间值域来建树,而hash为了不冲突要开的很大,所以值域就会比较的大,不过这道题好的一点是没有修改,所以直接离散一下就会小很多
2.hash的时候多mod (' ' )
3.mod 的值可以稍微取大一点
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 typedef long long ll; 8 9 const ll maxn = 200010; 10 const ll mod = (ll)1e14 + 7; 11 const ll p = 37; 12 13 ll a[maxn], b[maxn], pos[maxn], v[maxn], f[maxn], num = 0, n, m, k; 14 15 ll int_get() { 16 ll x = 0; char c = (char)getchar(); bool f = 0; 17 while(!isdigit(c) && c != '-') c = (char)getchar(); 18 if(c == '-') c = (char)getchar(), f = 1; 19 while(isdigit(c)) { 20 x = x * 10 + (int)(c - '0'); 21 c = (char)getchar(); 22 } 23 if(f) x = -x; 24 return x; 25 } 26 27 struct node { 28 ll data; 29 node *l, *r; 30 }e[maxn * 20]; ll ne = 0; 31 node* root[maxn]; 32 33 void test(node* x, ll l, ll r) { 34 if(!x) return; 35 cout << l <<" "<< r << " "<< x-> data << endl; 36 if(l ^ r) { 37 ll mid = (l + r) >> 1; 38 test(x-> l, l, mid), test(x-> r, mid + 1, r); 39 } 40 } 41 42 void insert(node* &x, node* y, ll l, ll r, ll v) { 43 if(!x) x = e + ne ++; 44 if(l == r) x-> data = (y ? y-> data : 0) + 1; 45 else { 46 ll mid = (l + r) >> 1; 47 if(v <= mid) { 48 if(y) x-> r = y-> r, y = y-> l; 49 insert(x-> l, y, l, mid, v); 50 } 51 else { 52 if(y) x-> l = y-> l, y = y-> r; 53 insert(x-> r, y, mid + 1, r, v); 54 } 55 } 56 } 57 58 ll ask(node* x, node* t, ll l, ll r, ll v) { 59 if(!x) return 0; 60 if(l == r) return x-> data - (t ? t-> data : 0); 61 else { 62 ll mid = (l + r) >> 1; 63 if(v <= mid) { 64 if(t) t = t-> l; 65 return ask(x-> l, t, l, mid, v); 66 } 67 else { 68 if(t) t = t-> r; 69 return ask(x-> r, t, mid + 1, r, v); 70 } 71 } 72 } 73 74 bool cmp(ll x, ll t) { 75 return b[x] < b[t]; 76 } 77 78 void pre(ll n) { 79 f[0] = 1; 80 for(ll i = 1; i <= n; ++ i) f[i] = f[i - 1] * p % mod; 81 } 82 83 ll find(ll x) { 84 ll l = 1, r = num + 1; 85 while(r - l > 1) { 86 ll mid = (l + r) >> 1; 87 if(b[pos[mid]] <= x) l = mid; 88 else r = mid; 89 } 90 return (x == b[pos[l]] ? v[pos[l]] : -1); 91 } 92 93 void read() { 94 n = int_get(), m = int_get(), k = int_get(); 95 pre(n); 96 for(ll i = 1; i <= n; ++ i) a[i] = int_get(); 97 memset(b, 0, sizeof(b)); 98 for(ll i = 1; i <= k; ++ i) b[1] = (b[1] * p % mod + a[i]) % mod; 99 for(ll j = k + 1; j <= n; ++ j) 100 b[j - k + 1] = (((b[j - k] - a[j - k] * f[k - 1] % mod) % mod + mod) % mod * p % mod + a[j]) % mod; 101 //for(ll i = 1; i <= n - k + 1; ++ i) cout << b[i] << endl; 102 //cout << endl; 103 for(int i = 1; i <= n - k + 1; ++ i) pos[i] = i; 104 sort(pos + 1, pos + 1 + n - k + 1, cmp); 105 v[pos[1]] = ++ num; 106 for(ll i = 2; i <= n - k + 1; ++ i) { 107 if(b[pos[i]] != b[pos[i - 1]]) ++ num; 108 v[pos[i]] = num; 109 } 110 for(ll i = 1; i <= n - k + 1; ++ i) insert(root[i], root[i - 1], 1, num, v[i]); 111 } 112 113 void sov() { 114 while(m --) { 115 ll ls, rs; 116 ls = int_get(); rs = int_get(); rs -= k - 1; 117 ll x = 0; 118 for(ll i = 1; i <= k; ++ i) { 119 ll s = int_get(); 120 x = (x * p % mod + s ) % mod; 121 } 122 ll c = find(x); 123 if(c == -1 || rs < ls) printf("Yes\n"); 124 else { 125 if(ask(root[rs], root[ls - 1], 1, num, c) > 0) printf("No\n"); 126 else printf("Yes\n"); 127 } 128 } 129 } 130 131 int main() { 132 //freopen("test.in", "r", stdin); 133 //freopen("test.out", "w", stdout); 134 read(); 135 //for(int i = 1; i <= n - k + 1; ++ i) test(root[i], 1, num), cout << endl; 136 sov(); 137 }