Advertisement
Guest User

Untitled

a guest
Apr 30th, 2016
365
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.39 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #define forn(i, n) for (int i = 0; i < int(n); i++)
  4. #define nfor(i, n) for (int i = int(n) - 1; i >= 0; i--)
  5. #define fore(i, l, r) for (int i = int(l); i < int(r); i++)
  6. #define correct(x, y, n, m) (0 <= (x) && (x) < (n) && 0 <= (y) && (y) < (m))
  7. #define all(a) (a).begin(), (a).end()
  8. #define sz(a) int((a).size())
  9. #define pb(a) push_back(a)
  10. #define mp(x, y) make_pair((x), (y))
  11. #define x first
  12. #define y second
  13.  
  14. using namespace std;
  15.  
  16. typedef long long li;
  17. typedef long double ld;
  18. typedef pair<int, int> pti;
  19.  
  20. template<typename X> inline X abs(const X& a) { return a < 0? -a: a; }
  21. template<typename X> inline X sqr(const X& a) { return a * a; }
  22.  
  23. template<typename A, typename B> inline ostream& operator<< (ostream& out, const pair<A, B>& p) { return out << "(" << p.x << ", " << p.y << ")"; }
  24. template<typename T> inline ostream& operator<< (ostream& out, const vector<T>& a) { out << "["; forn(i, sz(a)) { if (i) out << ','; out << ' ' << a[i]; } return out << " ]"; }
  25. template<typename T> inline ostream& operator<< (ostream& out, const set<T>& a) { return out << vector<T>(all(a)); }
  26. template<typename X, typename Y> inline ostream& operator<< (ostream& out, const map<X, Y>& a) { return out << vector<pair<X, Y>>(all(a)); }
  27. template<typename T> inline ostream& operator<< (ostream& out, pair<T*, int> a) { return out << vector<T>(a.x, a.x + a.y); }
  28.  
  29. inline ld gett() { return ld(clock()) / CLOCKS_PER_SEC; }
  30.  
  31. const int INF = int(1e9);
  32. const li INF64 = li(1e18);
  33. const ld EPS = 1e-9, PI = 3.1415926535897932384626433832795;
  34.  
  35. const int N = 500500, M = 50500, Q = 500500;
  36.  
  37. int n, m, k;
  38. char str[N];
  39. char buf[M];
  40. string a[M];
  41. pair<pti, pti> q[Q];
  42.  
  43. bool read() {
  44.     if (!gets(str)) return false;
  45.     n = int(strlen(str));
  46.     if (!n) return false;
  47.  
  48.     assert(cin >> m);
  49.     forn(i, m) {
  50.         assert(scanf("%s", buf) == 1);
  51.         a[i] = string(buf);
  52.     }
  53.  
  54.     assert(cin >> k);
  55.     forn(i, k) {
  56.         assert(scanf("%d%d%d%d", &q[i].y.x, &q[i].y.y, &q[i].x.x, &q[i].x.y) == 4);
  57.         q[i].x.x--;
  58.         q[i].y.x--;
  59.     }
  60.  
  61.     return true;
  62. }
  63.  
  64. struct node {
  65.     int l, r;
  66.     int parent, link;
  67.     map<int, int> next;
  68.     node(int l = 0, int r = 0, int parent = 0): l(l), r(r), parent(parent) {
  69.         link = -1;
  70.         next.clear();
  71.     }
  72. };
  73. struct state {
  74.     int v, pos;
  75.     state(int v = 0, int pos = 0): v(v), pos(pos) { }
  76. };
  77. const int L = N + 2 * M, S = 200, V = 2 * L, LOGV = 20;
  78. int l;
  79. int s[L];
  80. int tsz = 1;
  81. node t[V];
  82. state ptr;
  83. inline int len(int v) { return t[v].r - t[v].l; }
  84. inline int split(state st) {
  85.     if (st.pos == 0) return t[st.v].parent;
  86.     if (st.pos == len(st.v)) return st.v;
  87.     int cur = tsz++;
  88.     assert(cur < V);
  89.     t[cur] = node(t[st.v].l, t[st.v].l + st.pos, t[st.v].parent);
  90.     t[cur].next[s[t[st.v].l + st.pos]] = st.v;
  91.     t[t[st.v].parent].next[s[t[st.v].l]] = cur;
  92.     t[st.v].parent = cur;
  93.     t[st.v].l += st.pos;
  94.     return cur;
  95. }
  96. state go(state st, int l, int r) {
  97.     while (l < r) {
  98.         if (st.pos == len(st.v)) {
  99.             if (!t[st.v].next.count(s[l])) return state(-1, -1);
  100.             st = state(t[st.v].next[s[l]], 0);
  101.         } else {
  102.             if (s[t[st.v].l + st.pos] != s[l]) return state(-1, -1);
  103.             int d = min(len(st.v) - st.pos, r - l);
  104.             l += d;
  105.             st.pos += d;
  106.         }
  107.     }
  108.     return st;
  109. }
  110. int link(int v) {
  111.     int& ans = t[v].link;
  112.     if (ans != -1) return ans;
  113.     if (v == 0) return ans = 0;
  114.     int p = t[v].parent;
  115.     return ans = split(go(state(link(p), len(link(p))), t[v].l + (p == 0), t[v].r));
  116. }
  117. inline void treeExtand(int i) {
  118.     while (true) {
  119.         state next = go(ptr, i, i + 1);
  120.         if (next.v != -1) {
  121.             ptr = next;
  122.             break;
  123.         }
  124.         int mid = split(ptr), cur = tsz++;
  125.         assert(cur < V);
  126.         t[cur] = node(i, l, mid);
  127.         t[mid].next[s[i]] = cur;
  128.         if (mid == 0) break;
  129.         ptr = state(link(mid), len(link(mid)));
  130.     }
  131. }
  132.  
  133. vector<int> sharpPos;
  134.  
  135. void prepareSuffixTree() {
  136.     l = 0;
  137.     t[0] = node();
  138.     tsz = 1;
  139.  
  140.     sharpPos.clear();
  141.     sharpPos.reserve(m + 1);
  142.  
  143.     forn(i, n) s[l++] = (int) str[i];
  144.     sharpPos.pb(l);
  145.     s[l++] = S;
  146.  
  147.     forn(i, m) {
  148.         forn(j, sz(a[i]))
  149.             s[l++] = (int) a[i][j];
  150.         sharpPos.pb(l);
  151.         s[l++] = S + i + 1;
  152.     }
  153.  
  154.     forn(i, l) treeExtand(i);
  155. }
  156.  
  157. int p[LOGV][V], pd[LOGV][V];
  158.  
  159. int getParent(int v, int d) {
  160.     nfor(i, LOGV)
  161.         if (pd[i][v] <= d) {
  162.             d -= pd[i][v];
  163.             v = p[i][v];
  164.         }
  165.     return v;
  166. }
  167.  
  168. void prepareBinaryLifts() {
  169.     forn(i, tsz) {
  170.         p[0][i] = t[i].parent;
  171.         pd[0][i] = len(i);
  172.     }
  173.  
  174.     fore(i, 1, LOGV)
  175.         forn(j, tsz) {
  176.             p[i][j] = p[i - 1][p[i - 1][j]];
  177.             pd[i][j] = pd[i - 1][j] + pd[i - 1][p[i - 1][j]];
  178.         }
  179. }
  180.  
  181. state sufPos[N];
  182.  
  183. void dfs1(int v, int d) {
  184.     int idx = int(lower_bound(all(sharpPos), t[v].l) - sharpPos.begin());
  185.     if (idx < sz(sharpPos) && sharpPos[idx] < t[v].r) {
  186.         if (idx == 0) {
  187.             int len = sharpPos[idx] - t[v].l;
  188.             d += len;
  189.             assert(d <= n);
  190.             sufPos[n - d] = state(v, len);
  191.         }
  192.         return;
  193.     }
  194.  
  195.     d += len(v);
  196.     for (auto e : t[v].next)
  197.         dfs1(e.y, d);
  198. }
  199.  
  200. int getv(int l, int r) {
  201.     int v = sufPos[l].v;
  202.     int extra = len(v) - sufPos[l].pos;
  203.     return getParent(v, (n - r) + extra);
  204. }
  205.  
  206. state go(string str) {
  207.     state st(0, 0);
  208.     forn(i, sz(str)) {
  209.         int c = (int) str[i];
  210.         if (st.pos == len(st.v)) {
  211.             assert(t[st.v].next.count(c));
  212.             st = state(t[st.v].next[c], 0);
  213.         }
  214.         assert(s[t[st.v].l + st.pos] == c);
  215.         st.pos++;
  216.     }
  217.     return st;
  218. }
  219.  
  220. void prepareSuffixes() {
  221.     dfs1(0, 0);
  222. #ifdef CHECK
  223.     forn(i, n) {
  224.         state st(0, 0);
  225.         fore(j, i, n) {
  226.             state st = go(string(str + i, str + j + 1));
  227.             //cerr << "st.v=" << st.v << " getv(i, j + 1)=" << getv(i, j + 1) << endl;
  228.             assert(st.v == getv(i, j + 1));
  229.         }
  230.     }
  231. #endif
  232. }
  233.  
  234. struct ctnode {
  235.     int key, prior;
  236.     int val;
  237.     int cnt;
  238.     pti maxv;
  239.     ctnode *l, *r;
  240. };
  241. typedef ctnode* tree;
  242.  
  243. void printRec(tree t) {
  244.     if (!t) return;
  245.     printRec(t->l);
  246.     cerr << mp(t->key, t->val) << ' ';
  247.     printRec(t->r);
  248. }
  249. void print(tree t) {
  250.     printRec(t);
  251.     cerr << endl;
  252. }
  253.  
  254. inline int getCnt(tree t) { return t ? t->cnt : 0; }
  255. inline pti getMax(tree t) { return t ? t->maxv : mp(-1, -1); }
  256.  
  257. inline void lift(tree t) {
  258.     if (!t) return;
  259.  
  260.     t->cnt = getCnt(t->l) + 1 + getCnt(t->r);
  261.  
  262.     t->maxv = mp(t->val, -t->key);
  263.     if (t->l) t->maxv = max(t->maxv, t->l->maxv);
  264.     if (t->r) t->maxv = max(t->maxv, t->r->maxv);
  265. }
  266.  
  267. void split(tree t, int key, tree& t1, tree& t2) {
  268.     if (!t) return void(t1 = t2 = NULL);
  269.  
  270.     if (key < t->key) {
  271.         t2 = t;
  272.         split(t2->l, key, t1, t2->l);
  273.         lift(t2);
  274.     } else {
  275.         t1 = t;
  276.         split(t1->r, key, t1->r, t2);
  277.         lift(t1);
  278.     }
  279. }
  280.  
  281. tree merge(tree t1, tree t2) {
  282.     if (!t1) return t2;
  283.     if (!t2) return t1;
  284.  
  285.     if (t1->prior > t2->prior) {
  286.         t1->r = merge(t1->r, t2);
  287.         lift(t1);
  288.         return t1;
  289.     }
  290.  
  291.     t2->l = merge(t1, t2->l);
  292.     lift(t2);
  293.     return t2;
  294. }
  295.  
  296. inline int myRand() { return abs((rand() << 16) ^ rand()); }
  297.  
  298. const int HS = 2 * V;
  299. queue<int> heappos;
  300. ctnode heap[HS];
  301.  
  302. void traverse(tree t, vector<pti>& vs) {
  303.     if (!t) return;
  304.     traverse(t->l, vs);
  305.     vs.pb(mp(t->key, t->val));
  306.     traverse(t->r, vs);
  307.     heappos.push(int(t - heap));
  308. }
  309.  
  310. inline void inc(tree& t, int key, int val) {
  311.     tree t1, t2, t3, t4;
  312.     split(t, key, t1, t2);
  313.     split(t1, key - 1, t3, t4);
  314.  
  315.     if (!t4) {
  316.         assert(!heappos.empty());
  317.         int pos = heappos.front();
  318.         heappos.pop();
  319.         t4 = &heap[pos];
  320.         t4->key = key;
  321.         t4->prior = myRand();
  322.         t4->val = 0;
  323.         t4->l = t4->r = NULL;
  324.     }
  325.     t4->val += val;
  326.     lift(t4);
  327.  
  328.     t = merge(merge(t3, t4), t2);
  329. }
  330.  
  331. inline pti getMax(tree& t, int l, int r) {
  332.     tree t1, t2, t3, t4;
  333.     split(t, r - 1, t1, t2);
  334.     split(t1, l - 1, t3, t4);
  335.     pti ans = getMax(t4);
  336.     t = merge(merge(t3, t4), t2);
  337.     return ans;
  338. }
  339.  
  340. tree mergeSTL(tree a, tree b) {
  341.     if (getCnt(a) < getCnt(b)) swap(a, b);
  342.  
  343.     vector<pti> bb;
  344.     bb.reserve(getCnt(b));
  345.     traverse(b, bb);
  346.  
  347.     for (auto p : bb)
  348.         inc(a, p.x, p.y);
  349.  
  350.     return a;
  351. }
  352.  
  353. pti ans[Q];
  354. vector<int> queries[V];
  355.  
  356. tree dfs2(int v) {
  357.     tree res = NULL;
  358.  
  359.     int idx = int(lower_bound(all(sharpPos), t[v].l) - sharpPos.begin());
  360.     //cerr << "v=" << v << " t[v].l=" << t[v].l << " t[v].r=" << t[v].r << " idx=" << idx << " sharpPos[idx]=" << sharpPos[idx] << endl;
  361.     if (idx < sz(sharpPos) && sharpPos[idx] < t[v].r) {
  362.         if (idx > 0) {
  363.             //cerr << "idx-1=" << idx - 1 << endl;
  364.             inc(res, idx - 1, +1);
  365.             assert(queries[v].empty());
  366.         }
  367.         return res;
  368.     }
  369.  
  370.     for (auto e : t[v].next) {
  371.         tree nt = dfs2(e.y);
  372.         res = mergeSTL(res, nt);
  373.     }
  374.  
  375.     for (int idx : queries[v]) {
  376.         pti p = getMax(res, q[idx].y.x, q[idx].y.y);
  377.         p.y *= -1;
  378.         if (p.x == -1) p = mp(0, q[idx].y.x);
  379.         swap(p.x, p.y);
  380.         //cerr << "idx=" << idx << " p=" << p << endl;
  381.         ans[idx] = p;
  382.     }
  383.  
  384.     //cerr << "v=" << v << endl;
  385.     //print(res);
  386.     return res;
  387. }
  388.  
  389. void processQueries() {
  390.     while (!heappos.empty()) heappos.pop();
  391.     forn(i, HS) heappos.push(i);
  392.  
  393.     forn(i, tsz) queries[i].clear();
  394.  
  395.     forn(i, k) {
  396.         int v = getv(q[i].x.x, q[i].x.y);
  397.         queries[v].pb(i);
  398.         ans[i] = mp(-1, -1);
  399.     }
  400.  
  401.     dfs2(0);
  402.  
  403.     //cerr << "s: " << mp(s, l) << endl;
  404.     //cerr << "sharpPos: " << sharpPos << endl;
  405.     forn(i, k) {
  406.         if (ans[i] == mp(-1, -1)) ans[i] = mp(q[i].y.x, 0);
  407.         printf("%d %d\n", ans[i].x + 1, ans[i].y);
  408.     }
  409. }
  410.  
  411. void solve() {
  412.     prepareSuffixTree();
  413.     prepareBinaryLifts();
  414.     prepareSuffixes();
  415.     processQueries();
  416. }
  417.  
  418. int main() {
  419. #ifdef SU1
  420.     assert(freopen("input.txt", "rt", stdin));
  421.     //assert(freopen("output.txt", "wt", stdout));
  422. #endif
  423.    
  424.     cout << setprecision(10) << fixed;
  425.     cerr << setprecision(5) << fixed;
  426.  
  427.     while (read()) {
  428.         ld stime = gett();
  429.         solve();
  430.         cerr << "Time: " << gett() - stime << endl;
  431.         //break;
  432.     }
  433.    
  434.     return 0;
  435. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement