Advertisement
BaoJIaoPisu

Untitled

Nov 18th, 2022
731
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.12 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. using ll = long long;
  6. using ld = long double;
  7. using ull = unsigned long long;
  8.  
  9. using pii = pair<int, int>;
  10. using pll = pair<ll, ll>;
  11. using pld = pair<ld, ld>;
  12.  
  13. #define fi first
  14. #define se second
  15. #define left BAO
  16. #define right ANH
  17. #define pb push_back
  18. #define pf push_front
  19. #define mp make_pair
  20. #define ins insert
  21. #define btpc __builtin_popcount
  22. #define btclz __builtin_clz
  23.  
  24. #define sz(x) (int)(x.size());
  25. #define all(x) x.begin(), x.end()
  26. #define debug(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
  27.  
  28. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  29.  
  30. int d4x[4] = {1, 0, -1, 0}; int d4y[4] = {0, 1, 0, -1};
  31. int d8x[8] = {0, 1, 1, 1, 0, -1, -1, -1};
  32. int d8y[8] = {1, 1, 0, -1, -1, -1, 0, 1};
  33.  
  34. template<class X, class Y>
  35.     bool minimize(X &x, const Y &y) {
  36.         if (x > y)
  37.         {
  38.             x = y;
  39.             return true;
  40.         }
  41.         return false;
  42.     }
  43. template<class X, class Y>
  44.     bool maximize(X &x, const Y &y) {
  45.         if (x < y)
  46.         {
  47.             x = y;
  48.             return true;
  49.         }
  50.         return false;
  51.     }
  52.  
  53. const int MOD = 1e9 + 7; //998244353
  54.  
  55. template<class X, class Y>
  56.     void add(X &x, const Y &y) {
  57.         x = (x + y);
  58.         if(x >= MOD) x -= MOD;
  59.     }
  60.  
  61. template<class X, class Y>
  62.     void sub(X &x, const Y &y) {
  63.         x = (x - y);
  64.         if(x < 0) x += MOD;
  65.     }
  66.  
  67. /* Author : Le Ngoc Bao Anh, 12A5, LQD High School for Gifted Student*/
  68.  
  69. const ll INF = 1e9;
  70. const int N = 1e5 + 10;
  71. const int LOG = 16;
  72.  
  73. struct SegmentTree {
  74.     int n;
  75.     struct NODE {
  76.         int val = 0;
  77.     };
  78.  
  79.     vector<NODE> Node;
  80.  
  81.     SegmentTree(int _n = 0) {
  82.         n = _n;
  83.         Node.resize(4 * n + 7);
  84.     }
  85.  
  86. private:
  87.     NODE merge(const NODE &a, const NODE &b) {
  88.         NODE ans;
  89.         ans.val = max(a.val, b.val);
  90.         return ans;
  91.     }
  92.  
  93.     void Build(int L, int R, int id, ll v[]) {
  94.         if(L == R) {
  95.             Node[id].val = v[L];
  96.             return;
  97.         }
  98.  
  99.         int mid = (L + R) >> 1;
  100.         Build(L, mid, id << 1, v);
  101.         Build(mid + 1, R, id << 1 | 1, v);
  102.         Node[id] = merge(Node[id << 1], Node[id << 1 | 1]);
  103.     }
  104.  
  105.     void Update(int L, int R, int pos, ll val, int id) {
  106.         if(L == R) {
  107.             Node[id].val = val;
  108.             return;        
  109.         }
  110.  
  111.         int mid = (L + R) >> 1;
  112.         if(pos <= mid) Update(L, mid, pos, val, id << 1);
  113.         else Update(mid + 1, R, pos, val, id << 1 | 1);
  114.         Node[id] = merge(Node[id << 1], Node[id << 1 | 1]);
  115.     }
  116.  
  117.     NODE Get(int L, int R, int lo, int hi, int id) {
  118.         if(L > hi || R < lo) return NODE();
  119.         if(lo <= L && R <= hi) return Node[id];
  120.         int mid = (L + R) >> 1;
  121.         NODE l = Get(L, mid, lo, hi, id << 1);
  122.         NODE r = Get(mid + 1, R, lo, hi, id << 1 | 1);
  123.         return merge(l, r);
  124.     }
  125.  
  126. public:
  127.     void build(ll v[]) {
  128.         Build(1, n, 1, v);
  129.     }
  130.  
  131.     void update(int pos, ll val) {
  132.         Update(1, n, pos, val, 1);
  133.     }
  134.  
  135.     ll get(int L, int R) {
  136.         NODE ans = Get(1, n, L, R, 1);
  137.         return ans.val;
  138.     }
  139. };
  140.  
  141. struct Node {
  142.     Node* child[2];
  143.     int pos;
  144.  
  145.     Node() {
  146.         child[0] = child[1] = nullptr;
  147.         pos = 0;
  148.     }
  149. };
  150.  
  151. auto addTrie(Node *node, string &s, int id) {
  152.     int n = s.size();
  153.     for(int i = 0; i < n; i++) {
  154.         int p = (s[i] - '0');
  155.         if(node->child[p] == nullptr) node->child[p] = new Node();
  156.         node = node->child[p];
  157.         node->pos = id;
  158.     }
  159. }
  160.  
  161. int getTrie(Node *node, string &s, int pos, int lim) {
  162.     while(pos < s.size()) {
  163.         int p = s[pos] - '0';
  164.         p ^= 1;
  165.  
  166.         int index = (node->child[p] != nullptr ? node->child[p]->pos : INF);
  167.    
  168.         if(index <= lim) {
  169.             node = node->child[p];
  170.         } else {
  171.             node = node->child[p ^ 1];
  172.         }
  173.         pos++;
  174.     }
  175.  
  176.     return node->pos;
  177. }
  178.  
  179. struct Queries {
  180.     int r;
  181.     string s;
  182.     int id;
  183. };
  184. vector<Queries> larquery[N], squery[N];
  185. struct LQuery {
  186.     int l, r;
  187.     string s;
  188.     int id;
  189. };
  190. vector<LQuery> lquery;
  191. Node* root[N];
  192. Node* croot[N], *stNode[N];
  193.  
  194. string x[N];
  195. int f[N][LOG + 2], res[N], Index[N];
  196. vector<int> B[N * 10];
  197. vector<int> pos[N];
  198.  
  199. void BaoJiaoPisu() {
  200.     int n, q; cin >> n >> q;
  201.     for(int i = 1; i <= n; i++) {
  202.         cin >> x[i];
  203.         int len = x[i].size();
  204.         f[i][0] = len;
  205.         pos[len].pb(i);
  206.         if(root[len] == nullptr) root[len] = new Node();
  207.     }
  208.  
  209.     for(int j = 1; j <= LOG; j++) {
  210.         for(int i = 1; i <= n - (1 << j) + 1; i++) {
  211.             int u = i + (1 << (j - 1));
  212.             f[i][j] = max(f[i][j - 1], f[u][j - 1]);
  213.         }
  214.     }
  215.  
  216.     auto query = [&](int l, int r) -> int {
  217.         int x = 31 - btclz(r - l + 1);
  218.         return max(f[l][x], f[r - (1 << x) + 1][x]);
  219.     };
  220.  
  221.     for(int i = 1; i <= q; i++) {
  222.         int l, r; string s;
  223.         cin >> l >> r >> s;
  224.         int len = s.size();
  225.         int max_len = query(l, r);
  226.         if(max_len > len) {
  227.             lquery.pb({l, r, s, i});
  228.             larquery[l].pb({r, s, i});
  229.         } else {
  230.             squery[l].pb({r, s, i});
  231.         }
  232.     }
  233.  
  234.     auto found = [&](int l, int r, int len) -> bool {
  235.         int Index = lower_bound(all(pos[len]), l) - pos[len].begin();
  236.         return (Index < pos[len].size() && pos[len][Index] <= r);
  237.     };
  238.  
  239.     for(int i = n; i >= 1; i--) {
  240.         addTrie(root[x[i].size()], x[i], i);
  241.         for(auto &query : squery[i]) {
  242.             int l = i;
  243.             int r = query.r;
  244.             int id = query.id;
  245.             string &s = query.s;
  246.             int len = s.size();
  247.  
  248.             int request = 0;
  249.             for(int i = 0; i < len; i++) {
  250.                 if(s[i] == '0') {
  251.                     if(found(l, r, len - i)) {
  252.                         request = len - i;
  253.                         break;
  254.                     }
  255.                 }
  256.             }
  257.  
  258.             if(!request) {
  259.                 for(int i = 1; i <= len; i++) {
  260.                     request = i;
  261.                     break;
  262.                 }
  263.             }  
  264.  
  265.             res[id] = getTrie(root[request], query.s, len - request, r);
  266.         }
  267.     }
  268.  
  269.     //difficult case : when ai.size() > x.size();
  270.  
  271.     SegmentTree IT = SegmentTree(n);
  272.     sort(all(lquery), [&](LQuery &_a, LQuery &_b) {
  273.         return _a.s.size() > _b.s.size();
  274.     });
  275.  
  276.     for(int i = 1; i <= n; i++) {
  277.         B[x[i].size() + 1].pb(i);
  278.         Index[i] = 1;
  279.         croot[i] = root[x[i].size()];
  280.         addTrie(root[x[i].size()], x[i], INF);
  281.     }
  282.  
  283.     int iter = 1e6;
  284.     for(int i = 0; i < lquery.size(); i++) {
  285.         int l = lquery[i].l, r = lquery[i].r, id = lquery[i].id;
  286.         string &s = lquery[i].s;
  287.         int len = s.size();
  288.  
  289.         while(iter - 1 > len) {
  290.             vector<int> one, zero;
  291.             for(auto id : B[iter]) {
  292.                 int p = (x[id][x[id].size() - iter + 1] - '0');
  293.                 if(p) one.pb(id);
  294.                 else zero.pb(id);
  295.             }
  296.  
  297.             //merge-sort
  298.             int i = 0, j = 0, curr = (B[iter - 1].size() > 0);
  299.             if(B[iter - 1].size() > 0) {
  300.                 croot[1] = root[iter - 2];
  301.             }
  302.             pii last = mp(-1, -1);
  303.             while(i < one.size() && j < zero.size()) {
  304.                 int x = one[i];
  305.                 int y = zero[j];
  306.  
  307.                 if(Index[x] >= Index[y]) {
  308.                     B[iter - 1].pb(y);
  309.                     if(last != mp(Index[y], 0)) {
  310.                         ++curr;
  311.                         croot[curr] = croot[Index[y]]->child[0];
  312.                     }
  313.                     last = mp(Index[y], 0);
  314.                     ++j;
  315.                     Index[y] = curr;
  316.                 } else {
  317.                     B[iter - 1].pb(x);
  318.                     if(last != mp(Index[x], 1)) {
  319.                         ++curr;
  320.                         croot[curr] = croot[Index[x]]->child[1];
  321.                     }
  322.                     last = mp(Index[x], 1);
  323.                     ++i;
  324.                     Index[x] = curr;
  325.                 }
  326.             }
  327.  
  328.             while(i < one.size()) {
  329.                 int x = one[i];
  330.                 B[iter - 1].pb(x);
  331.                 if(last != mp(Index[x], 1)) {
  332.                     ++curr;
  333.                     croot[curr] = croot[Index[x]]->child[1];
  334.                 }
  335.                 last = mp(Index[x], 1);
  336.                 ++i;
  337.                 Index[x] = curr;
  338.             }
  339.  
  340.             while(j < zero.size()) {
  341.                 int y = zero[j];
  342.                 B[iter - 1].pb(y);
  343.                 if(last != mp(Index[y], 0)) {
  344.                     ++curr;
  345.                     croot[curr] = croot[Index[y]]->child[0];   
  346.                 }
  347.                 last = mp(Index[y], 0);
  348.                 ++j;
  349.                 Index[y] = curr;
  350.             }
  351.  
  352.             iter--;
  353.             if(iter == 3) {
  354.                 for(auto x : B[iter]) cout << x << " " << Index[x] << endl;
  355.                 cout << endl;
  356.             }
  357.             for(auto id : B[iter]) {
  358.                 IT.update(id, Index[id]);
  359.             }
  360.         }
  361.  
  362.         stNode[id] = croot[IT.get(l, r)];
  363.     }
  364.  
  365.     for(int i = n; i >= 1; i--) {
  366.         addTrie(root[x[i].size()], x[i], i);
  367.         for(auto query : larquery[i]) {
  368.             int r = query.r, id = query.id;
  369.             string &s = query.s;
  370.             int len = s.size();
  371.  
  372.             res[id] = getTrie(stNode[id], s, 0, r);
  373.         }
  374.     }
  375.  
  376.     for(int i = 1; i <= q; i++) {
  377.         cout << res[i] << '\n';
  378.     }
  379. }  
  380.  
  381. int main()
  382. {
  383.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  384.     #ifndef ONLINE_JUDGE
  385.     freopen("input.txt", "r", stdin);
  386.     freopen("output.txt", "w", stdout);
  387.     #else
  388.     //online
  389.     #endif
  390.  
  391.     int tc = 1, ddd = 0;
  392.     // cin >> tc;
  393.     while(tc--) {
  394.         //ddd++;
  395.         //cout << "Case #" << ddd << ": ";
  396.         BaoJiaoPisu();
  397.     }
  398. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement