Dang_Quan_10_Tin

adbrack (VNOJ)

Jul 11th, 2024
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.86 KB | None | 0 0
  1. // https://oj.vnoi.info/problem/adbrack
  2.  
  3. #include <bits/stdc++.h>
  4.  
  5. using namespace std;
  6. using ll = long long;
  7. using ld = long double;
  8. using ull = unsigned long long;
  9.  
  10. constexpr bool typetest = 0;
  11. constexpr int N = 1e2 + 5;
  12.  
  13. /// M là số chữ số ước lượng, nhớ thay đổi với các bài/ Bản dùng vector (an toàn) ở đây: https://pastebin.com/tvmKwAQA
  14. /// Nếu không có phép nhân thì nên đẩy BASE lên 1e17 hoặc 1e18
  15. /// a = Bignum(5) || a = Bignum("5") đều được, tuy nhiên khuyến khích dùng loại 1
  16. /// cin >> a hay a.read() đều được
  17. /// cout << a hay a.print() đều được, khuyến khích dùng loại 1
  18. /// Phép chia và phép mod chỉ dùng cho số nguyên và cho ra kết quả nguyên
  19. /// Phép nhân fft
  20.  
  21. using cd = complex<long double>;
  22. const long double PI = acos(-1);
  23. const int M = 100;
  24. const ll BASE = 1e7;
  25. const int gd = log10(BASE);
  26. const int maxn = M / gd + 1;
  27. struct Bignum
  28. {
  29.     int n;
  30.     ll a[maxn];
  31.     Bignum(ll x = 0)
  32.     {
  33.         memset(a, 0, sizeof a);
  34.         n = 0;
  35.         do
  36.         {
  37.             a[n++] = x % BASE;
  38.             x /= BASE;
  39.         } while (x);
  40.     }
  41.     Bignum(const string &s)
  42.     {
  43.         Convert(s);
  44.     }
  45.     ll stoll(const string &s)
  46.     {
  47.         ll ans(0);
  48.         for (auto i : s)
  49.             ans = ans * 10 + i - '0';
  50.         return ans;
  51.     }
  52.     void Convert(const string &s)
  53.     {
  54.         memset(a, 0, sizeof a);
  55.         n = 0;
  56.         for (int i = s.size() - 1; ~i; --i)
  57.         {
  58.             int j = max(0, i - gd + 1);
  59.             a[n++] = stoll(s.substr(j, i - j + 1));
  60.             i = j;
  61.         }
  62.         fix();
  63.     }
  64.     void fix()
  65.     {
  66.         ++n;
  67.         for (int i = 0; i < n - 1; ++i)
  68.         {
  69.             a[i + 1] += a[i] / BASE;
  70.             a[i] %= BASE;
  71.             if (a[i] < 0)
  72.             {
  73.                 a[i] += BASE;
  74.                 --a[i + 1];
  75.             }
  76.         }
  77.         while (n > 1 && a[n - 1] == 0)
  78.             --n;
  79.     }
  80.     Bignum &operator+=(const Bignum &x)
  81.     {
  82.         n = max(n, x.n);
  83.         for (int i = 0; i < n; ++i)
  84.             a[i] += x.a[i];
  85.         fix();
  86.         return *this;
  87.     }
  88.     Bignum &operator-=(const Bignum &x)
  89.     {
  90.         for (int i = 0; i < x.n; ++i)
  91.             a[i] -= x.a[i];
  92.         fix();
  93.         return *this;
  94.     }
  95.     void fft(vector<cd> &a, bool invert)
  96.     {
  97.         int n = a.size();
  98.  
  99.         for (int i = 1, j = 0; i < n; i++)
  100.         {
  101.             int bit = n >> 1;
  102.             for (; j & bit; bit >>= 1)
  103.                 j ^= bit;
  104.             j ^= bit;
  105.  
  106.             if (i < j)
  107.                 swap(a[i], a[j]);
  108.         }
  109.  
  110.         for (int len = 2; len <= n; len <<= 1)
  111.         {
  112.             double ang = 2 * PI / len * (invert ? -1 : 1);
  113.             cd wlen(cos(ang), sin(ang));
  114.             for (int i = 0; i < n; i += len)
  115.             {
  116.                 cd w(1);
  117.                 for (int j = 0; j < len / 2; j++)
  118.                 {
  119.                     cd u = a[i + j], v = a[i + j + len / 2] * w;
  120.                     a[i + j] = u + v;
  121.                     a[i + j + len / 2] = u - v;
  122.                     w *= wlen;
  123.                 }
  124.             }
  125.         }
  126.  
  127.         if (invert)
  128.         {
  129.             for (cd &x : a)
  130.                 x /= n;
  131.         }
  132.     }
  133.     Bignum &operator*=(const Bignum &x)
  134.     {
  135.         int m = 1;
  136.         while (m < n + x.n)
  137.             m <<= 1;
  138.         vector<cd> fa(m), fb(m);
  139.         for (int i = 0; i < m; ++i)
  140.         {
  141.             fa[i] = a[i];
  142.             fb[i] = x.a[i];
  143.         }
  144.         fft(fa, false); /// dft
  145.         fft(fb, false); /// dft
  146.         for (int i = 0; i < m; i++)
  147.             fa[i] *= fb[i];
  148.         fft(fa, true); ///Interpolation
  149.         n = m;
  150.         for (int i = 0; i < n; ++i)
  151.             a[i] = round(fa[i].real());
  152.         fix();
  153.         return *this;
  154.     }
  155.     Bignum &operator/=(const ll &x)
  156.     {
  157.         ll r = 0ll;
  158.         for (int i = n - 1; i > -1; --i)
  159.         {
  160.             r = r * BASE + a[i];
  161.             a[i] = r / x;
  162.             r %= x;
  163.         }
  164.         fix();
  165.         return *this;
  166.     }
  167.     Bignum operator+(const Bignum &s)
  168.     {
  169.         Bignum c;
  170.         copy(a, a + n, c.a);
  171.         c.n = n;
  172.         c += s;
  173.         return c;
  174.     }
  175.     Bignum operator-(const Bignum &s)
  176.     {
  177.         Bignum c;
  178.         copy(a, a + n, c.a);
  179.         c.n = n;
  180.         c -= s;
  181.         return c;
  182.     }
  183.     Bignum operator*(const Bignum &s)
  184.     {
  185.         Bignum c;
  186.         copy(a, a + n, c.a);
  187.         c.n = n;
  188.         c *= s;
  189.         return c;
  190.     }
  191.     Bignum operator/(const ll &x)
  192.     {
  193.         Bignum c;
  194.         copy(a, a + n, c.a);
  195.         c.n = n;
  196.         c /= x;
  197.         return c;
  198.     }
  199.     ll operator%(const ll &x)
  200.     {
  201.         ll ans(0);
  202.         for (int i = n - 1; ~i; --i)
  203.             ans = (ans * BASE + a[i]) % x;
  204.         return ans;
  205.     }
  206.     int com(const Bignum &s) const
  207.     {
  208.         if (n < s.n)
  209.             return 1;
  210.         if (n > s.n)
  211.             return 2;
  212.         for (int i = n - 1; i > -1; --i)
  213.             if (a[i] > s.a[i])
  214.                 return 2;
  215.             else if (a[i] < s.a[i])
  216.                 return 1;
  217.         return 3;
  218.     }
  219.     bool operator<(const Bignum &s) const
  220.     {
  221.         return com(s) == 1;
  222.     }
  223.     bool operator>(const Bignum &s) const
  224.     {
  225.         return com(s) == 2;
  226.     }
  227.     bool operator==(const Bignum &s) const
  228.     {
  229.         return com(s) == 3;
  230.     }
  231.     bool operator<=(const Bignum &s) const
  232.     {
  233.         return com(s) != 2;
  234.     }
  235.     bool operator>=(const Bignum &s) const
  236.     {
  237.         return com(s) != 1;
  238.     }
  239.     void read()
  240.     {
  241.         string s;
  242.         cin >> s;
  243.         Convert(s);
  244.     }
  245.     void print()
  246.     {
  247.         int i = n;
  248.         while (i > 0 && a[i] == 0)
  249.             --i;
  250.         cout << a[i];
  251.         for (--i; ~i; --i)
  252.             cout << setw(gd) << setfill('0') << a[i];
  253.     }
  254.     friend istream &operator>>(istream &in, Bignum &x)
  255.     {
  256.         string s;
  257.         in >> s;
  258.         x.Convert(s);
  259.         return in;
  260.     }
  261.     friend ostream &operator<<(ostream &out, const Bignum &x)
  262.     {
  263.         int i = x.n;
  264.         while (i > 0 && x.a[i] == 0)
  265.             --i;
  266.         out << x.a[i];
  267.         for (--i; ~i; --i)
  268.             out << setw(gd) << setfill('0') << x.a[i];
  269.         return out;
  270.     }
  271. };
  272.  
  273. char open[] = {'(', '[', '{'},
  274.      close[] = {')', ']', '}'};
  275.  
  276. int n, k;
  277. Bignum dp[N][N / 2], ans(0), Pow[N / 2];
  278. string s;
  279.  
  280. void Read()
  281. {
  282.     //freopen("test.INP", "r", stdin);
  283.     //freopen("test.OUT", "w", stdout);
  284.     cin >> n >> k >> s;
  285.     s = " " + s;
  286. }
  287.  
  288. void Solve()
  289. {
  290.     dp[0][0] = Pow[0] = Bignum(1);
  291.     for (int i = 1; i <= n; ++i)
  292.     {
  293.         for (int j = 0; j <= n - i && j <= i && j <= k; ++j)
  294.         {
  295.             dp[i][j] = dp[i - 1][j + 1];
  296.             if (j)
  297.                 dp[i][j] += dp[i - 1][j - 1];
  298.         }
  299.         if (i <= n / 2)
  300.             Pow[i] = Pow[i - 1] * Bignum(3);
  301.     }
  302.  
  303.     string cnt;
  304.     cnt.reserve(n);
  305.  
  306.     for (int i = 1; i <= n; ++i)
  307.     {
  308.         for (int j = 0; j < 3 && open[j] < s[i]; ++j)
  309.             if (!((n - i - (cnt.size() + 1)) & 1))
  310.                 ans += Pow[(n - i - (cnt.size() + 1)) / 2] * dp[n - i][cnt.size() + 1];
  311.  
  312.         if (cnt.size() && cnt.back() < s[i])
  313.             ans += Pow[(n - i - (cnt.size() - 1)) / 2] * dp[n - i][cnt.size() - 1];
  314.  
  315.         if (s[i] == '(' || s[i] == '[' || s[i] == '{')
  316.             cnt.push_back(s[i] == '(' ? ')' : (s[i] == '[' ? ']' : '}'));
  317.         else
  318.             cnt.pop_back();
  319.  
  320.         //cout << i << " " << ans << "\n";
  321.     }
  322.  
  323.     cout << ans + 1;
  324. }
  325.  
  326. int32_t main()
  327. {
  328.     ios::sync_with_stdio(0);
  329.     cin.tie(0);
  330.     cout.tie(0);
  331.     int t(1);
  332.     if (typetest)
  333.         cin >> t;
  334.     for (int _ = 1; _ <= t; ++_)
  335.     {
  336.         Read();
  337.         Solve();
  338.     }
  339. }
  340.  
Advertisement
Add Comment
Please, Sign In to add comment