This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub tko919/library
#define PROBLEM "https://judge.yosupo.jp/problem/static_range_inversions_query" #include "Template/template.hpp" #include "Algorithm/mo.hpp" #include "DataStructure/bit.hpp" int a[101010]; ll ret[101010],cur=0; BIT<int> bit(101010); int main(){ int n,q; cin>>n>>q; using P=pair<int,int>; vector<P> vs(n); rep(i,0,n){ cin>>vs[i].first; vs[i].second=i; } sort(ALL(vs)); rep(i,0,n)a[vs[i].second]=i; auto addl=[&](int i){ cur+=bit.sum(a[i]); bit.add(a[i],1); }; auto addr=[&](int i){ cur+=bit.all-bit.sum(a[i]); bit.add(a[i],1); }; auto dell=[&](int i){ bit.add(a[i],-1); cur-=bit.sum(a[i]); }; auto delr=[&](int i){ bit.add(a[i],-1); cur-=bit.all-bit.sum(a[i]); }; auto out=[&](int i){ ret[i]=cur; }; Mo mo(n); rep(i,0,q){ int L,R; cin>>L>>R; mo.add(L,R); } mo.run(addl,addr,dell,delr,out); rep(i,0,q)cout<<ret[i]<<'\n'; return 0; }
#line 1 "Verify/LC_static_range_inversions_query.test.cpp" #define PROBLEM "https://judge.yosupo.jp/problem/static_range_inversions_query" #line 1 "Template/template.hpp" #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++) #define rrep(i, a, b) for (int i = (int)(b-1); i >= (int)(a); i--) #define ALL(v) (v).begin(), (v).end() #define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end()) #define SZ(v) (int)v.size() #define MIN(v) *min_element(ALL(v)) #define MAX(v) *max_element(ALL(v)) #define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin()) #define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin()) using uint = unsigned int; using ll = long long int; using ull = unsigned long long; using i128 = __int128_t; using u128 = __uint128_t; const int inf = 0x3fffffff; const ll INF = 0x1fffffffffffffff; template <typename T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return 1; } return 0; } template <typename T> inline bool chmin(T &a, T b) { if (a > b) { a = b; return 1; } return 0; } template <typename T, typename U> T ceil(T x, U y) { assert(y != 0); if (y < 0) x = -x, y = -y; return (x > 0 ? (x + y - 1) / y : x / y); } template <typename T, typename U> T floor(T x, U y) { assert(y != 0); if (y < 0) x = -x, y = -y; return (x > 0 ? x / y : (x - y + 1) / y); } template <typename T> int popcnt(T x) { return __builtin_popcountll(x); } template <typename T> int topbit(T x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); } template <typename T> int lowbit(T x) { return (x == 0 ? -1 : __builtin_ctzll(x)); } #ifdef LOCAL #define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__) #else #define show(...) true #endif template <typename T> void _show(int i, T name) { cerr << '\n'; } template <typename T1, typename T2, typename... T3> void _show(int i, const T1 &a, const T2 &b, const T3 &...c) { for (; a[i] != ',' && a[i] != '\0'; i++) cerr << a[i]; cerr << ":" << b << " "; _show(i + 1, a, c...); } template <class T, class U> ostream &operator<<(ostream &os, const pair<T, U> &p) { os << "P(" << p.first << ", " << p.second << ")"; return os; } template <typename T, template <class> class C> ostream &operator<<(ostream &os, const C<T> &v) { os << "["; for (auto d : v) os << d << ", "; os << "]"; return os; } #line 2 "Algorithm/mo.hpp" struct Mo{ const int n; vector<int> L,R; Mo(int _n):n(_n){} void add(int lb,int rb){ L.push_back(lb); R.push_back(rb); } template <typename AL, typename AR, typename DL, typename DR, typename OUT> void run(const AL& addl,const AR& addr,const DL& dell,const DR& delr,const OUT& out){ const int q=L.size(); const int w=max<int>(1,1.0*n/max<double>(1.0,sqrt(q*2.0/3.0))); vector<int> ord(q); iota(ALL(ord),0); sort(ALL(ord),[&](int i,int j){ int a=L[i]/w,b=L[j]/w; if(a!=b)return a<b; if(a&1)return R[i]<R[j]; else return R[i]>R[j]; }); int lb=0,rb=0; for(auto& i:ord){ while(lb>L[i])addl(--lb); while(rb<R[i])addr(rb++); while(lb<L[i])dell(lb++); while(rb>R[i])delr(--rb); out(i); } } }; /** * @brief Mo's Algorithm * @docs docs/mo.md */ #line 2 "DataStructure/bit.hpp" template<typename T>struct BIT{ int n; T all=0; vector<T> val; BIT(int _n=0):n(_n),val(_n+10){} void clear(){val.assign(n+10,0); all=T();} void add(int i,T x){ for(i++;i<=n;i+=(i&-i))val[i]=val[i]+x; all+=x; } T sum(int i){ T res=0; for(;i;i-=(i&-i))res+=val[i]; return res; } T sum(int L,int R){return sum(R)-sum(L);} // [L,R) int lower_bound(T x){ int ret=0,len=1; while(2*len<=n)len<<=1; for(;len>=1;len>>=1){ if(ret+len<=n and val[ret+len]<x){ ret+=len; x-=val[ret]; } } return ret; } }; /** * @brief Binary Indexed Tree */ #line 6 "Verify/LC_static_range_inversions_query.test.cpp" int a[101010]; ll ret[101010],cur=0; BIT<int> bit(101010); int main(){ int n,q; cin>>n>>q; using P=pair<int,int>; vector<P> vs(n); rep(i,0,n){ cin>>vs[i].first; vs[i].second=i; } sort(ALL(vs)); rep(i,0,n)a[vs[i].second]=i; auto addl=[&](int i){ cur+=bit.sum(a[i]); bit.add(a[i],1); }; auto addr=[&](int i){ cur+=bit.all-bit.sum(a[i]); bit.add(a[i],1); }; auto dell=[&](int i){ bit.add(a[i],-1); cur-=bit.sum(a[i]); }; auto delr=[&](int i){ bit.add(a[i],-1); cur-=bit.all-bit.sum(a[i]); }; auto out=[&](int i){ ret[i]=cur; }; Mo mo(n); rep(i,0,q){ int L,R; cin>>L>>R; mo.add(L,R); } mo.run(addl,addr,dell,delr,out); rep(i,0,q)cout<<ret[i]<<'\n'; return 0; }