Advertisement
fooker

abc346G

Mar 23rd, 2024
720
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.79 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4.  
  5. const ll nmax = 1e9+7;
  6. const ll nmax2 = 998244353;
  7.  
  8. #include <ext/pb_ds/assoc_container.hpp>
  9. #include <ext/pb_ds/tree_policy.hpp>
  10. #include <ext/pb_ds/detail/standard_policies.hpp>
  11. using namespace __gnu_pbds;
  12. typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
  13. typedef tree<std::pair<ll, ll>, null_type, less<std::pair<ll,ll>>, rb_tree_tag, tree_order_statistics_node_update> ordered_set_pair;
  14.  
  15. struct segment_tree {
  16.     ll n;
  17.     struct node {
  18.         ll sum;
  19.         ll maximum;
  20.         ll minimum;
  21.         bool lazytag;
  22.     };
  23.  
  24.     std::vector<node> tree;
  25.  
  26.     node combine(node n1, node n2){
  27.         node n3;
  28.         n3.sum = n1.sum + n2.sum;
  29.         n3.maximum = std::max(n1.maximum, n2.maximum);
  30.         n3.minimum = std::min(n1.minimum, n2.minimum);
  31.         n3.lazytag = false;
  32.         return n3;
  33.     }
  34.  
  35.     segment_tree (const std::vector<ll> &a){
  36.         n = a.size();
  37.         tree.resize(4 * n + 5);
  38.         build_segment_tree(a, 1, 1, n);
  39.     }
  40.  
  41.     void build_segment_tree(const std::vector<ll> &a, ll v, ll l, ll r){
  42.         if (l == r){
  43.             tree[v].sum = 0;
  44.             tree[v].maximum = 0;
  45.             tree[v].minimum = 0;
  46.             return;
  47.         }
  48.         ll mid = (l + r) >> 1;
  49.         build_segment_tree(a, 2 * v, l, mid);
  50.         build_segment_tree(a, 2 * v + 1, mid + 1, r);
  51.         tree[v] = combine(tree[2 * v], tree[2 * v + 1]);
  52.     }
  53.  
  54.     void propogate(ll v, ll l, ll mid, ll r){
  55.         if (tree[v].lazytag){
  56.             tree[v].lazytag = false;
  57.             tree[2 * v].lazytag = true;
  58.             tree[2 * v + 1].lazytag = true;
  59.  
  60.             ll extra = (tree[v].sum - (tree[2 * v].sum + tree[2 * v + 1].sum)) / (r - l + 1);
  61.             tree[2 * v].sum += extra * (mid - l + 1);
  62.             tree[2 * v + 1].sum += extra * (r - mid);
  63.  
  64.             tree[2 * v].minimum = tree[v].minimum;
  65.             tree[2 * v + 1].minimum = tree[v].minimum;
  66.  
  67.             tree[2 * v].maximum = tree[v].maximum;
  68.             tree[2 * v + 1].maximum = tree[v].maximum;  
  69.         }
  70.     }
  71.  
  72.     void range_update(ll v, ll l, ll r, ll tl, ll tr, ll val){
  73.         if (l > r or r < tl or tr > l) return;
  74.         if (tl <= l and r <= tr){
  75.             tree[v].lazytag = true;
  76.             tree[v].maximum += val;
  77.             tree[v].minimum += val;
  78.             tree[v].sum += (r - l + 1) * val;
  79.             return;
  80.         }
  81.         ll mid = (l + r) >> 1;
  82.         propogate(v, l, mid, r);
  83.         range_update(2 * v, l, mid, tl, tr, val);
  84.         range_update(2 * v + 1, mid + 1, r, tl, tr, val);
  85.     }
  86.  
  87.     void range_update(ll l, ll r, ll val){
  88.         range_update(1, 1, n, l, r, val);
  89.     }
  90.  
  91.     ll range_query(ll v, ll l, ll r, ll tl, ll tr){
  92.         if (l > r or r < tl or tr > l) return 0;
  93.         if (tl <= l and r <= tr){
  94.             if (tree[v].maximum == 0) return (r - l + 1);
  95.             if (tree[v].minimum > 0) return 0;
  96.             if (l == r){
  97.                 return 0;
  98.             }
  99.         }
  100.         ll mid = (l + r) >> 1;
  101.         propogate(v, l, mid, r);
  102.         return range_query(2 * v, l, mid, tl, tr) + range_query(2 * v + 1, mid + 1, r, tl, tr);
  103.     }
  104.  
  105.     ll range_query(ll l, ll r){
  106.         return range_query(1, 1, n, l, r);
  107.     }
  108. };
  109.  
  110. void solve(){
  111.     ll n;
  112.     std::cin >> n;
  113.  
  114.     std::vector<ll> cont[n + 1];
  115.     for (ll i = 1; i <= n; i++){
  116.         cont[i].push_back(0);
  117.     }
  118.    
  119.     ll a[n + 1];
  120.  
  121.     for (ll i = 1; i <= n; i++){
  122.         std::cin >> a[i];
  123.         cont[a[i]].push_back(i);
  124.     }
  125.  
  126.     for (ll i = 1; i <= n; i++){
  127.         cont[i].push_back(n + 1);
  128.     }
  129.  
  130.     std::vector<std::pair<ll, ll>> start[n + 1];
  131.     std::vector<std::pair<ll, ll>> end[n + 1];
  132.  
  133.     for (ll i = 1; i <= n; i++){
  134.         if (cont[i].size() <= 2) continue;
  135.         for (ll j = 1; j < cont[i].size() - 1; j++){
  136.             start[cont[i][j - 1] + 1].push_back({cont[i][j], cont[i][j + 1] - 1});
  137.             end[cont[i][j]].push_back({cont[i][j], cont[i][j + 1] - 1});
  138.         }
  139.     }
  140.  
  141.     std::vector<ll> b(n + 1);
  142.     segment_tree segtree(b);
  143.  
  144.     ll ans = 0;
  145.     for (ll i = 1; i <= n; i++){
  146.         if (start[i].size()){
  147.             for (auto u: start[i]){
  148.                 segtree.range_update(u.first, u.second, 1);
  149.             }
  150.         }
  151.        
  152.         ans += (n - segtree.range_query(1, n));
  153.  
  154.         if (end[i].size()){
  155.             for (auto u: end[i]){
  156.                 segtree.range_update(u.first, u.second, -1);
  157.             }
  158.         }
  159.     }
  160.  
  161.     std::cout << ans << '\n';
  162. }
  163.  
  164. int main(){
  165.     std::ios_base::sync_with_stdio(false);
  166.     std::cin.tie(0);
  167.     std::cout.tie(0);
  168.  
  169.     int t = 1;
  170.     // std::cin >> t;
  171.    
  172.     while(t--){
  173.         solve();
  174.     }
  175.     return 0;
  176. }
  177.  
  178.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement