Advertisement
Dang_Quan_10_Tin

B 8.11.2021

Nov 8th, 2021
691
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.53 KB | None | 0 0
  1. #define task ""
  2.  
  3. #include <iostream>
  4. #include <cstdio>
  5. #include <vector>
  6. #include <cstring>
  7.  
  8. using namespace std;
  9.  
  10. using ll = long long;
  11. using ld = long double;
  12.  
  13. constexpr int N = 3e3 + 5;
  14. constexpr int mod = 1e9 + 7;
  15.  
  16. inline void Add(int &x, int y)
  17. {
  18.     (x += y) %= mod;
  19. }
  20.  
  21. struct FenwickTree
  22. {
  23.     int n;
  24.     int a[N];
  25.  
  26.     FenwickTree()
  27.     {
  28.         memset(a, 0, sizeof a);
  29.     }
  30.  
  31.     void Update(int p, int v)
  32.     {
  33.         for (; p <= n; p += p & -p)
  34.             Add(a[p], v);
  35.     }
  36.  
  37.     int Get(int p)
  38.     {
  39.         if (p == 0)
  40.             return 1;
  41.         int ans(0);
  42.         for (; p; p -= p & -p)
  43.             Add(ans, a[p]);
  44.         return ans;
  45.     }
  46. } f[N], g;
  47.  
  48. int n, a[N];
  49. vector<int> s; // stack imple by vector
  50.  
  51. void Read()
  52. {
  53.     cin >> n;
  54.     g.n = n; // g[u] = sum dp[u][k]
  55.     for (int i = 1; i <= n; ++i)
  56.     {
  57.         cin >> a[i];
  58.         f[i].n = n; // dp[j][i] với i là chỉ số còn j là số gạch (Đảo lại để tiện việc cập nhật)
  59.     }
  60. }
  61.  
  62. void Solve()
  63. {
  64.     for (int i = 1; i <= n; ++i)
  65.     {
  66.         while (!s.empty() && a[s.back()] < a[i])
  67.             s.pop_back();
  68.        
  69.         //Cập nhật cho những thằng có số gạch là a[i]
  70.         //dp[t][a[i]] = sum g[j] với j từ s.back() -> i-1
  71.        
  72.         for (int j = i - 1; j >= (s.empty() ? 0 : s.back()); --j)
  73.         {
  74.             int v = g.Get(j); // v = g[j]
  75.             f[a[i]].Update(j + 1, v); // dp[t][a[i]] += g[j]
  76.             f[a[i]].Update(i + 1, -v);
  77.  
  78.             g.Update(j + 1, v); // cập nhật dp, đồng thời cập nhật tổng g[] của dp[][]
  79.             g.Update(i + 1, -v);
  80.         }
  81.  
  82.         // Cập nhật riêng cho dp[i][]
  83.         // dp[i][j] = tổng dp[i-1][u] với u cũng trong s và u ≥ v
  84.         for (int j = 0, v = 0; j < (int)s.size(); ++j)
  85.         {
  86.             Add(v, f[a[s[j]]].Get(i - 1)); // v += dp[i - 1][a[s[j]]]
  87.             f[a[s[j]]].Update(i, v);
  88.             f[a[s[j]]].Update(i + 1, -v);
  89.  
  90.             g.Update(i, v);
  91.             g.Update(i + 1, -v);
  92.         }
  93.  
  94.         s.emplace_back(i);
  95.     }
  96.  
  97.     /*for (int i = 1; i <= n; ++i)
  98.     {
  99.         cout << i << ": ";
  100.         for (int j = 1; j <= n; ++j)
  101.             cout << f[i].Get(j) << " ";
  102.         cout << "\n";
  103.     }*/
  104.  
  105.     cout << g.Get(n);
  106. }
  107.  
  108. int32_t main()
  109. {
  110.     ios::sync_with_stdio(0);
  111.     cin.tie(0);
  112.     cout.tie(0);
  113.     if (fopen(task ".INP", "r"))
  114.     {
  115.         freopen(task ".INP", "r", stdin);
  116.         freopen(task ".OUT", "w", stdout);
  117.     }
  118.     Read();
  119.     Solve();
  120. }
  121.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement