Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define task ""
- #include <iostream>
- #include <cstdio>
- #include <vector>
- #include <cstring>
- using namespace std;
- using ll = long long;
- using ld = long double;
- constexpr int N = 3e3 + 5;
- constexpr int mod = 1e9 + 7;
- inline void Add(int &x, int y)
- {
- (x += y) %= mod;
- }
- struct FenwickTree
- {
- int n;
- int a[N];
- FenwickTree()
- {
- memset(a, 0, sizeof a);
- }
- void Update(int p, int v)
- {
- for (; p <= n; p += p & -p)
- Add(a[p], v);
- }
- int Get(int p)
- {
- if (p == 0)
- return 1;
- int ans(0);
- for (; p; p -= p & -p)
- Add(ans, a[p]);
- return ans;
- }
- } f[N], g;
- int n, a[N];
- vector<int> s; // stack imple by vector
- void Read()
- {
- cin >> n;
- g.n = n; // g[u] = sum dp[u][k]
- for (int i = 1; i <= n; ++i)
- {
- cin >> a[i];
- 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)
- }
- }
- void Solve()
- {
- for (int i = 1; i <= n; ++i)
- {
- while (!s.empty() && a[s.back()] < a[i])
- s.pop_back();
- //Cập nhật cho những thằng có số gạch là a[i]
- //dp[t][a[i]] = sum g[j] với j từ s.back() -> i-1
- for (int j = i - 1; j >= (s.empty() ? 0 : s.back()); --j)
- {
- int v = g.Get(j); // v = g[j]
- f[a[i]].Update(j + 1, v); // dp[t][a[i]] += g[j]
- f[a[i]].Update(i + 1, -v);
- g.Update(j + 1, v); // cập nhật dp, đồng thời cập nhật tổng g[] của dp[][]
- g.Update(i + 1, -v);
- }
- // Cập nhật riêng cho dp[i][]
- // dp[i][j] = tổng dp[i-1][u] với u cũng trong s và u ≥ v
- for (int j = 0, v = 0; j < (int)s.size(); ++j)
- {
- Add(v, f[a[s[j]]].Get(i - 1)); // v += dp[i - 1][a[s[j]]]
- f[a[s[j]]].Update(i, v);
- f[a[s[j]]].Update(i + 1, -v);
- g.Update(i, v);
- g.Update(i + 1, -v);
- }
- s.emplace_back(i);
- }
- /*for (int i = 1; i <= n; ++i)
- {
- cout << i << ": ";
- for (int j = 1; j <= n; ++j)
- cout << f[i].Get(j) << " ";
- cout << "\n";
- }*/
- cout << g.Get(n);
- }
- int32_t main()
- {
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- if (fopen(task ".INP", "r"))
- {
- freopen(task ".INP", "r", stdin);
- freopen(task ".OUT", "w", stdout);
- }
- Read();
- Solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement