Guest User

Untitled

a guest
Dec 12th, 2020
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.58 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define sim template < class c
  4. #define ris return * this
  5. #define dor > debug & operator <<
  6. #define eni(x) sim > typename \
  7.   enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
  8. sim > struct rge { c b, e; };
  9. sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
  10. sim > auto dud(c* x) -> decltype(cerr << *x, 0);
  11. sim > char dud(...);
  12. struct debug {
  13. #ifdef LOCAL
  14. ~debug() { cerr << endl; }
  15. eni(!=) cerr << boolalpha << i; ris; }
  16. eni(==) ris << range(begin(i), end(i)); }
  17. sim, class b dor(pair < b, c > d) {
  18.   ris << "(" << d.first << ", " << d.second << ")";
  19. }
  20. sim dor(rge<c> d) {
  21.   *this << "[";
  22.   for (auto it = d.b; it != d.e; ++it)
  23.     *this << ", " + 2 * (it == d.b) << *it;
  24.   ris << "]";
  25. }
  26. #else
  27. sim dor(const c&) { ris; }
  28. #endif
  29. };
  30. #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
  31. // debug & operator << (debug & dd, P p) { dd << "(" << p.x << ", " << p.y << ")"; return dd; }
  32.  
  33. // ALCS, https://www.sciencedirect.com/science/article/pii/S0166218X07002727
  34. vector<vector<int>> get_ih(string a, string b) {
  35.     int na = a.length();
  36.     int nb = b.length();
  37.     vector<vector<int>> ih(na + 1, vector<int>(nb + 1));
  38.     auto iv = ih;
  39.     for(int j = 0; j <= nb; ++j) {
  40.         ih[0][j] = j;
  41.     }
  42.     for(int l = 0; l <= na; ++l) {
  43.         iv[l][0] = 0;
  44.     }
  45.     for(int l = 1; l <= na; ++l) {
  46.         for(int j = 1; j <= nb; ++j) {
  47.             if(a[l-1] != b[j-1]) {
  48.                 ih[l][j] = max(iv[l][j-1], ih[l-1][j]);
  49.                 iv[l][j] = min(iv[l][j-1], ih[l-1][j]);
  50.             }
  51.             else {
  52.                 ih[l][j] = iv[l][j-1];
  53.                 iv[l][j] = ih[l-1][j];
  54.             }
  55.         }
  56.     }
  57.     return ih;
  58. }
  59.  
  60. int one[3005], two[3005];
  61. int last_size;
  62. void get_row(int A, int b_high, const vector<vector<int>>& ih, int ans[]) {
  63.     // a[0..A] with b[low..]
  64.     A++;
  65.     b_high++;
  66.     for(int i = 0; i <= b_high; ++i) {
  67.         ans[i] = 0;
  68.     }
  69.     for(int j = 1; j <= b_high; ++j) {
  70.         int L = ih[A][j];
  71.         int R = j - 1;
  72.         if(L <= R) {
  73.             ans[L]++;
  74.             if(R + 1 < b_high) {
  75.                 ans[R+1]--;
  76.             }
  77.             // for(int i = L; i <= R; ++i) {
  78.                 // ans[i]++;
  79.             // }
  80.         }
  81.         // in[A][j] .. j - 1
  82.     }
  83.     for(int i = 1; i < b_high; ++i) {
  84.         ans[i] += ans[i-1];
  85.     }
  86.     /*for(int b_low = 0; b_low < b_high; ++b_low) {
  87.         int pref = 0;
  88.         for(int j = b_low + 1; j <= b_high; ++j) {
  89.             if(b_low >= ih[A][j]) {
  90.                 pref++;
  91.             }
  92.         }
  93.         ans.push_back(pref);
  94.     }*/
  95.     ans[b_high] = 0;
  96.     last_size = b_high + 1;
  97.     reverse(ans, ans + last_size);
  98.     // reverse(ans.begin(), ans.end());
  99.     // return ans;
  100.     // return answer;
  101. };
  102.  
  103. string read() {
  104.     static char s[3005];
  105.     scanf("%s", s);
  106.     return string(s);
  107. }
  108. struct Query {
  109.     int la, ra, lb, rb, id;
  110.     void read(int _id) {
  111.         id = _id;
  112.         scanf("%d%d%d%d", &la, &ra, &lb, &rb);
  113.         la--; ra--; lb--; rb--;
  114.     }
  115. };
  116.  
  117. vector<int> print;
  118.  
  119. void rec_solve(string a, string b, vector<Query>& queries) {
  120.     if(/*(int) a.length() < 5 && */ queries.empty()) {
  121.         return;
  122.     }
  123.     if(a.length() < b.length()) {
  124.         swap(a, b);
  125.         for(Query& query : queries) {
  126.             swap(query.la, query.lb);
  127.             swap(query.ra, query.rb);
  128.         }
  129.     }
  130.    
  131.     int na = a.length();
  132.     int nb = b.length();
  133.    
  134.     const int mid = na / 2;
  135.     string a_left = a.substr(0, mid);
  136.     string a_right = a.substr(mid);
  137.     // debug() << imie(a_left) imie(a_right);
  138.     vector<vector<int>> ih_right = get_ih(a_right, b);
  139.     reverse(a_left.begin(), a_left.end());
  140.     reverse(b.begin(), b.end());
  141.     vector<vector<int>> ih_left = get_ih(a_left, b);
  142.     // vector<vector<int>> ih_right = get_ih(a_right, b);
  143.     reverse(a_left.begin(), a_left.end());
  144.     reverse(b.begin(), b.end());
  145.    
  146.     vector<Query> left_queries, right_queries;
  147.    
  148.     for(Query query : queries) {
  149.         int la = query.la, ra = query.ra, lb = query.lb, rb = query.rb;
  150.         if((ra - la + 1) * (rb - lb + 1) <= 1000 || (int) queries.size() <= 10) {
  151.             int len_a = ra - la + 1;
  152.             int len_b = rb - lb + 1;
  153.             vector<int> dp(len_b + 1);
  154.             for(int i = 0; i < len_a; ++i) {
  155.                 for(int j = len_b - 1; j >= 0; --j) {
  156.                     if(a[la+i] == b[lb+j]) {
  157.                         dp[j+1] = dp[j] + 1;
  158.                     }
  159.                 }
  160.                 for(int j = 0; j < len_b; ++j) {
  161.                     dp[j+1] = max(dp[j+1], dp[j]);
  162.                 }
  163.             }
  164.             print[query.id] = dp.back();
  165.             continue;
  166.         }
  167.         if(ra < mid) {
  168.             left_queries.push_back(query);
  169.             continue;
  170.         }
  171.         if(la >= mid) {
  172.             query.la -= mid;
  173.             query.ra -= mid;
  174.             right_queries.push_back(query);
  175.             continue;
  176.         }
  177.         // if(la < mid && ra >= mid) {
  178.         get_row(mid - 1 - la, nb - 1 - lb, ih_left, one);
  179.         int one_size = last_size;
  180.         get_row(ra - mid, rb, ih_right, two);
  181.         int two_size = last_size;
  182.         // debug() << imie(one) imie(two);
  183.         int answer = 0;
  184.         for(int i = 0; i < one_size; ++i) {
  185.             int j = rb-lb+1 - i;
  186.             if(0 <= j && j < two_size) {
  187.                 answer = max(answer, one[i] + two[j]);
  188.             }
  189.         }
  190.         print[query.id] = answer;
  191.             // printf("%d\n", answer);
  192.         // }
  193.         /*
  194.         else { // brute force
  195.             assert(false);
  196.             // puts("?");
  197.             // continue;
  198.             vector<vector<int>> ih = get_ih(a.substr(la), b);
  199.             int A = ra - la;
  200.             int b_low = lb, b_high = rb;
  201.            
  202.             // a[0..A] with b[low..]
  203.             A++;
  204.             b_high++;
  205.             int answer = 0;
  206.             for(int j = b_low + 1; j <= b_high; ++j) {
  207.                 if(b_low >= ih[A][j]) {
  208.                     answer++;
  209.                 }
  210.             }
  211.             print[query.id] = answer;
  212.             // printf("%d\n", answer);
  213.         }*/
  214.     }
  215.     rec_solve(a_left, b, left_queries);
  216.     rec_solve(a_right, b, right_queries);
  217. }
  218.  
  219. int main() {
  220.     // string a = "yxxyzyzx";
  221.     // string b = "yxxyzxyzxyxzx";
  222.    
  223.     int na, nb, q;
  224.     scanf("%d%d%d", &na, &nb, &q);
  225.     string a = read();
  226.     string b = read();
  227.    
  228.     vector<Query> queries(q);
  229.     for(int i = 0; i < q; ++i) {
  230.         queries[i].read(i);
  231.     }
  232.     print.resize(q, -1);
  233.    
  234.     rec_solve(a, b, queries);
  235.    
  236.     for(int x : print) {
  237.         printf("%d\n", x);
  238.     }
  239. }
Advertisement
Add Comment
Please, Sign In to add comment