1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| #include <bits/stdc++.h> #define int long long #define chmax(x, y) x = max(x, y) #define chmin(x, y) x = min(x, y) #define SP << " " << #define fish signed using namespace std; mt19937 rnd(1209); const int INF = 0x3f3f3f3f3f3f3f3f; const int base = 66683, N = 1e6 + 10, base2 = 131, mod = 998244353; unsigned long long prod[N], h[N]; long long prod2[N], h2[N]; unsigned long long get(int l, int r) {return h[r] - h[l - 1] * prod[r - l + 1];} int get2(int l, int r) {return ((h2[r] - h2[l - 1] * prod2[r - l + 1] % mod) % mod + mod) % mod;} int sl[N], sr[N], t[N]; char a[N]; int mn[N << 2]; #define ls(u) (u << 1) #define rs(u) (u << 1 | 1) void modify(int u, int l, int r, int pos, int k) { if(l == r) { mn[u] = k; return ; } int mid = l + r >> 1; if(pos <= mid) modify(ls(u), l, mid, pos, k); else modify(rs(u), mid + 1, r, pos, k); mn[u] = min(mn[u << 1],mn[u << 1 | 1]); } int query(int u, int l, int r, int ql, int qr) { if(ql <= l && r <= qr) return mn[u]; int mid = l + r >> 1, res = INF; if(ql <= mid) chmin(res, query(ls(u), l, mid, ql, qr)); if(qr > mid) chmin(res, query(rs(u), mid + 1, r, ql, qr)); return res; } struct node {int l, r, id;} ; int ans[N]; vector<node> vp[N]; vector<node> vq[N]; fish main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n; cin >> n; int hh = n + 1, tt = n; for(int i = 1; i <= n; i ++) { char ch; cin >> ch; if('A' <= ch && ch <= 'Z') a[++ tt] = ch - 'A' + 'a'; else a[-- hh] = ch; sl[i] = hh, sr[i] = tt; } prod[0] = prod2[0] = 1; for(int i = 1; i <= n; i ++) prod[i] = prod[i - 1] * base; for(int i = hh; i <= tt; i ++) h[i] = h[i - 1] * base + (unsigned long long)a[i]; for(int i = 1; i <= n; i ++) prod2[i] = (prod2[i - 1] * base2) % mod; for(int i = hh; i <= tt; i ++) h2[i] = (h2[i - 1] * base2 % mod + a[i]) % mod; for(int i = 1; i <= n; i ++) { int l = i, r = n, res = i; while(l <= r) { int mid = l + r >> 1; int l1 = sl[mid], l2 = sl[mid] + i; int r1 = sr[mid] - i, r2 = sr[mid]; if(get(l1, r1) == get(l2, r2) && get2(l1, r1) == get2(l2, r2)) l = mid + 1, res = mid; else r = mid - 1; } t[i] = res; } int m; cin >> m; for(int i = 1; i <= m; i ++) {int x; cin >> x; vp[t[x]].push_back({i, x});} memset(mn, 0x3f, sizeof mn); int q; cin >> q; for(int i = 1; i <= q; i ++) {int k, l, r; cin >> k >> l >> r; vq[k].push_back({l, r, i});} for(int i = n; i >= 1; i --) { for(auto v : vp[i]) modify(1, 1, m, v.l, v.r); for(auto v : vq[i]) {ans[v.id] = query(1, 1, m, v.l, v.r); if(ans[v.id] > i) ans[v.id] = -1;} } for(int i = 1; i <= q; i ++) cout << ans[i] << "\n"; return 0; }
|