Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef LOCAL
- #pragma GCC optimize ("O3")
- //#pragma GCC optimize ("unroll-loops")
- #endif
- #include <bits/stdc++.h>
- using namespace std;
- //fast IO by yosupo
- //sc.read(string) だと append される
- struct Scanner {
- FILE* fp = nullptr;
- char line[(1 << 15) + 1];
- size_t st = 0, ed = 0;
- void reread() {
- memmove(line, line + st, ed - st);
- ed -= st;
- st = 0;
- ed += fread(line + ed, 1, (1 << 15) - ed, fp);
- line[ed] = '\0';
- }
- bool succ() {
- while (true) {
- if (st == ed) {
- reread();
- if (st == ed) return false;
- }
- while (st != ed && isspace(line[st])) st++;
- if (st != ed) break;
- }
- if (ed - st <= 50) reread();
- return true;
- }
- template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
- bool read_single(T& ref) {
- if (!succ()) return false;
- while (true) {
- size_t sz = 0;
- while (st + sz < ed && !isspace(line[st + sz])) sz++;
- ref.append(line + st, sz);
- st += sz;
- if (!sz || st != ed) break;
- reread();
- }
- return true;
- }
- template <class T, enable_if_t<is_integral<T>::value, int> = 0>
- bool read_single(T& ref) {
- if (!succ()) return false;
- bool neg = false;
- if (line[st] == '-') {
- neg = true;
- st++;
- }
- ref = T(0);
- while (isdigit(line[st])) {
- ref = 10 * ref + (line[st++] - '0');
- }
- if (neg) ref = -ref;
- return true;
- }
- template <class T> bool read_single(vector<T>& ref) {
- for (auto& d : ref) {
- if (!read_single(d)) return false;
- }
- return true;
- }
- void read() {}
- template <class H, class... T> void read(H& h, T&... t) {
- bool f = read_single(h);
- assert(f);
- read(t...);
- }
- Scanner(FILE* _fp) : fp(_fp) {}
- };
- struct Printer {
- public:
- template <bool F = false> void write() {}
- template <bool F = false, class H, class... T>
- void write(const H& h, const T&... t) {
- if (F) write_single(' ');
- write_single(h);
- write<true>(t...);
- }
- template <class... T> void writeln(const T&... t) {
- write(t...);
- write_single('\n');
- }
- Printer(FILE* _fp) : fp(_fp) {}
- ~Printer() { flush(); }
- private:
- static constexpr size_t SIZE = 1 << 15;
- FILE* fp;
- char line[SIZE], small[50];
- size_t pos = 0;
- void flush() {
- fwrite(line, 1, pos, fp);
- pos = 0;
- }
- void write_single(const char& val) {
- if (pos == SIZE) flush();
- line[pos++] = val;
- }
- template <class T, enable_if_t<is_integral<T>::value, int> = 0>
- void write_single(T val) {
- if (pos > (1 << 15) - 50) flush();
- if (val == 0) {
- write_single('0');
- return;
- }
- if (val < 0) {
- write_single('-');
- val = -val; // todo min
- }
- size_t len = 0;
- while (val) {
- small[len++] = char('0' + (val % 10));
- val /= 10;
- }
- for (size_t i = 0; i < len; i++) {
- line[pos + i] = small[len - 1 - i];
- }
- pos += len;
- }
- void write_single(const string& s) {
- for (char c : s) write_single(c);
- }
- void write_single(const char* s) {
- size_t len = strlen(s);
- for (size_t i = 0; i < len; i++) write_single(s[i]);
- }
- template <class T> void write_single(const vector<T>& val) {
- auto n = val.size();
- for (size_t i = 0; i < n; i++) {
- if (i) write_single(' ');
- write_single(val[i]);
- }
- }
- void write_single(long double d){
- {
- long long v=d;
- write_single(v);
- d-=v;
- }
- write_single('.');
- for(int _=0;_<8;_++){
- d*=10;
- long long v=d;
- write_single(v);
- d-=v;
- }
- }
- };
- Scanner sc(stdin);
- Printer pr(stdout);
- using ll=long long;
- //#define int ll
- #define rng(i,a,b) for(int i=int(a);i<int(b);i++)
- #define rep(i,b) rng(i,0,b)
- #define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
- #define per(i,b) gnr(i,0,b)
- #define pb push_back
- #define eb emplace_back
- #define a first
- #define b second
- #define bg begin()
- #define ed end()
- #define all(x) x.bg,x.ed
- #define si(x) int(x.size())
- #ifdef LOCAL
- #define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
- #else
- #define dmp(x) void(0)
- #endif
- template<class t,class u> bool chmax(t&a,u b){if(a<b){a=b;return true;}else return false;}
- template<class t,class u> bool chmin(t&a,u b){if(b<a){a=b;return true;}else return false;}
- template<class t> using vc=vector<t>;
- template<class t> using vvc=vc<vc<t>>;
- using pi=pair<int,int>;
- using vi=vc<int>;
- template<class t,class u>
- ostream& operator<<(ostream& os,const pair<t,u>& p){
- return os<<"{"<<p.a<<","<<p.b<<"}";
- }
- template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
- os<<"{";
- for(auto e:v)os<<e<<",";
- return os<<"}";
- }
- #define mp make_pair
- #define mt make_tuple
- #define one(x) memset(x,-1,sizeof(x))
- #define zero(x) memset(x,0,sizeof(x))
- #ifdef LOCAL
- void dmpr(ostream&os){os<<endl;}
- template<class T,class... Args>
- void dmpr(ostream&os,const T&t,const Args&... args){
- os<<t<<" ";
- dmpr(os,args...);
- }
- #define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
- #else
- #define dmp2(...) void(0)
- #endif
- using uint=unsigned;
- using ull=unsigned long long;
- template<class t,size_t n>
- ostream& operator<<(ostream&os,const array<t,n>&a){
- return os<<vc<t>(all(a));
- }
- template<int i,class T>
- void print_tuple(ostream&,const T&){
- }
- template<int i,class T,class H,class ...Args>
- void print_tuple(ostream&os,const T&t){
- if(i)os<<",";
- os<<get<i>(t);
- print_tuple<i+1,T,Args...>(os,t);
- }
- template<class ...Args>
- ostream& operator<<(ostream&os,const tuple<Args...>&t){
- os<<"{";
- print_tuple<0,tuple<Args...>,Args...>(os,t);
- return os<<"}";
- }
- template<class t>
- void print(t x,int suc=1){
- cout<<x;
- if(suc==1)
- cout<<"\n";
- if(suc==2)
- cout<<" ";
- }
- ll read(){
- ll i;
- cin>>i;
- return i;
- }
- vi readvi(int n,int off=0){
- vi v(n);
- rep(i,n)v[i]=read()+off;
- return v;
- }
- pi readpi(int off=0){
- int a,b;cin>>a>>b;
- return pi(a+off,b+off);
- }
- template<class t,class u>
- void print(const pair<t,u>&p,int suc=1){
- print(p.a,2);
- print(p.b,suc);
- }
- template<class T>
- void print(const vector<T>&v,int suc=1){
- rep(i,v.size())
- print(v[i],i==int(v.size())-1?suc:2);
- }
- template<class T,size_t N>
- void print(const array<T,N>&v,int suc=1){
- rep(i,N)
- print(v[i],i==int(N)-1?suc:2);
- }
- string readString(){
- string s;
- cin>>s;
- return s;
- }
- template<class T>
- T sq(const T& t){
- return t*t;
- }
- //#define CAPITAL
- void yes(bool ex=true){
- #ifdef CAPITAL
- cout<<"YES"<<"\n";
- #else
- cout<<"Yes"<<"\n";
- #endif
- if(ex)exit(0);
- #ifdef LOCAL
- cout.flush();
- #endif
- }
- void no(bool ex=true){
- #ifdef CAPITAL
- cout<<"NO"<<"\n";
- #else
- cout<<"No"<<"\n";
- #endif
- if(ex)exit(0);
- #ifdef LOCAL
- cout.flush();
- #endif
- }
- void possible(bool ex=true){
- #ifdef CAPITAL
- cout<<"POSSIBLE"<<"\n";
- #else
- cout<<"Possible"<<"\n";
- #endif
- if(ex)exit(0);
- #ifdef LOCAL
- cout.flush();
- #endif
- }
- void impossible(bool ex=true){
- #ifdef CAPITAL
- cout<<"IMPOSSIBLE"<<"\n";
- #else
- cout<<"Impossible"<<"\n";
- #endif
- if(ex)exit(0);
- #ifdef LOCAL
- cout.flush();
- #endif
- }
- constexpr ll ten(int n){
- return n==0?1:ten(n-1)*10;
- }
- const ll infLL=LLONG_MAX/3;
- #ifdef int
- const int inf=infLL;
- #else
- const int inf=INT_MAX/2-100;
- #endif
- int topbit(signed t){
- return t==0?-1:31-__builtin_clz(t);
- }
- int topbit(ll t){
- return t==0?-1:63-__builtin_clzll(t);
- }
- int botbit(signed a){
- return a==0?32:__builtin_ctz(a);
- }
- int botbit(ll a){
- return a==0?64:__builtin_ctzll(a);
- }
- int popcount(signed t){
- return __builtin_popcount(t);
- }
- int popcount(ll t){
- return __builtin_popcountll(t);
- }
- bool ispow2(int i){
- return i&&(i&-i)==i;
- }
- ll mask(int i){
- return (ll(1)<<i)-1;
- }
- bool inc(int a,int b,int c){
- return a<=b&&b<=c;
- }
- template<class t> void mkuni(vc<t>&v){
- sort(all(v));
- v.erase(unique(all(v)),v.ed);
- }
- ll rand_int(ll l, ll r) { //[l, r]
- static mt19937_64 gen;
- return uniform_int_distribution<ll>(l, r)(gen);
- }
- template<class t>
- void myshuffle(vc<t>&a){
- rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
- }
- template<class t>
- int lwb(const vc<t>&v,const t&a){
- return lower_bound(all(v),a)-v.bg;
- }
- vvc<int> readGraph(int n,int m){
- vvc<int> g(n);
- rep(i,m){
- int a,b;
- cin>>a>>b;
- //sc.read(a,b);
- a--;b--;
- g[a].pb(b);
- g[b].pb(a);
- }
- return g;
- }
- vvc<int> readTree(int n){
- return readGraph(n,n-1);
- }
- const int nmax=ten(6)+10;
- //assume z is strictly ascending
- //z に重要な点が入っていて
- //問題を解くべき区間 [l,r] というのは,[l,r] 内の重要な点の個数の密度が 1/k 以上
- //という状況の時,座標圧縮に似たことができて,必要な区間を列挙する.
- //線形時間
- vc<pi> getlr(int k,vi z){
- auto getval=[&](int i){return i*k-z[i];};
- vc<pi> hs;
- rep(i,si(z)){
- int lw=getval(i),up=lw+k-1;
- while(si(hs)&&hs.back().a<=up){
- chmin(lw,hs.back().a);
- chmax(up,hs.back().b);
- hs.pop_back();
- }
- hs.eb(lw,up);
- }
- int head=0;
- vc<pi> lr;
- for(auto [lw,up]:hs){
- int l=z[head]-(up-getval(head));
- while(head<si(z)&&lw<=getval(head))head++;
- int r=z[head-1]+1+(getval(head-1)+k-1-lw);
- lr.eb(l,r);
- }
- return lr;
- }
- vi ps[nmax];
- vc<pi> unko[nmax];
- int pool[ten(7)+10],phead;
- int num=0;
- struct Y{
- ll c;
- int n,*buf,rpre,rsum,lpre,lsum;
- void init(int col,int s){
- c=col;
- n=s;
- buf=pool+phead;
- phead+=s;
- }
- void clear(int buri){
- rep(i,n)buf[i]=0;
- rpre=lpre=buri;
- lsum=rsum=0;
- }
- ll left(int i,int w){
- //num++;
- //return 0;
- //assert(abs(lpre-i)<=1);
- if(lpre<i){
- lsum-=buf[++lpre];
- }
- if(lpre>i){
- lsum+=buf[lpre--];
- }
- buf[lpre]+=w;
- if(lpre<rpre)rsum+=w;
- return c*lsum*w;
- }
- ll right(int i,int w){
- //num++;
- //return 0;
- //assert(abs(rpre-i)<=1);
- if(rpre<i){
- rsum+=buf[rpre++];
- }
- if(rpre>i){
- rsum-=buf[--rpre];
- }
- buf[rpre]+=w;
- if(lpre<rpre)lsum+=w;
- return c*rsum*w;
- }
- } buf[nmax];
- int lastseen[nmax],kosuu[nmax];
- bool dbg=false;
- void slv(){
- int n,m;
- sc.read(n,m);
- if(n<0){
- n=-n;
- dbg=true;
- }
- vi abuf(n);
- rep(i,n){
- int a;
- if(dbg){
- a=rand_int(1,3);
- a=i%2+1;
- a=i%3+1;
- a*=n/3;
- }else{
- sc.read(a);
- }
- a--;
- ps[a].pb(i);
- abuf[i]=a;
- }
- vc<ll> rw(n+1,0);
- const int L=20;
- vi see(n,0);
- vc<pi> lrlist;
- int u=0;
- {
- vi tmp;
- rep(col,n)if(si(ps[col])){
- auto cur=getlr(2,ps[col]);
- int head=0;
- auto gethei=[&](int i){
- while(head<si(ps[col])&&ps[col][head]<i)
- head++;
- return head*2-i;
- };
- for(auto [l,r]:cur){
- l++;
- r--;
- tmp.clear();
- chmax(l,0);
- chmin(r,n);
- int lw=inf,up=-inf;
- rng(i,l,r+1){
- int h=gethei(i);
- tmp.pb(h);
- chmin(lw,h);
- chmax(up,h);
- }
- if(r-l<L){
- rng(i,l,r+1){
- rng(j,l,i){
- if(tmp[j-l]<tmp[i-l]){
- rw[i]+=col+1;
- }
- }
- }
- rng(i,l,r)if(abuf[i]==col)see[i]=col+1;
- }else{
- rng(i,l,r+1)
- unko[i].eb(u,tmp[i-l]-lw);
- buf[u++].init(col+1,up-lw+1);
- lrlist.eb(l,r+1);
- }
- }
- }
- }
- vi gomi(u);
- int norg=n;
- vc<ll> sing(n+2);
- rep(i,n+1)sing[i+1]=sing[i]+rw[i];
- vi xs;
- rep(i,n+1)if(si(unko[i]))xs.pb(i);
- n=si(xs);
- rep(i,n)unko[i]=unko[xs[i]];
- vi pre(n+1);
- rep(i,n)pre[i+1]=pre[i]+si(unko[i]);
- //cerr<<u<<endl;
- //cerr<<pre[n]<<endl;
- const int B=max<int>(pre[n]/sqrt(m),1);
- //const int B=4000;
- //cerr<<B<<endl;
- struct Q{
- int l,r,i;
- };
- vc<Q> qs(m);
- vc<ll> res(m);
- int curtime=0;
- rep(idx,m){
- int l,r;
- if(dbg){
- do{
- l=rand_int(1,norg);
- //r=rand_int(1,norg);
- r=norg;
- }while(l>r);
- }else{
- sc.read(l,r);
- }
- l--;r++;
- res[idx]=sing[r]-sing[l];
- rng(i,l,min(l+L,r)){
- res[idx]-=rw[i];
- }
- //dmp(res[idx]);
- rng(i,l,min(l+L,r)){
- curtime++;
- int tot=0,mx=0,val=0;
- gnr(j,l,i){
- int v=see[j];
- if(lastseen[v]<curtime){
- lastseen[v]=curtime;
- kosuu[v]=0;
- }
- if(chmax(mx,++kosuu[v])){
- val=v;
- }
- tot++;
- //dmp2(j,i,tot,mx,val);
- if(mx*2>tot)res[idx]+=val;
- }
- }
- qs[idx]={lwb(xs,l),lwb(xs,r),idx};
- }
- //cerr<<114514<<endl;
- sort(all(qs),[&](const Q&a,const Q&b){
- int x=pre[a.l]/B,y=pre[b.l]/B;
- if(x!=y)return x<y;
- return a.r<b.r;
- });
- ll ans=0;
- auto clear=[&](int pos){
- ans=0;
- rep(col,u){
- if(lrlist[col].a<=pos)gomi[col]=0;
- else gomi[col]=buf[col].n-1;
- }
- for(auto [c,h]:unko[pos]){
- gomi[c]=h;
- }
- rep(col,u){buf[col].clear(gomi[col]);}
- };
- auto addL=[&](int i){
- for(auto [c,h]:unko[i]){
- ans+=buf[c].left(h,1);
- }
- };
- auto delL=[&](int i){
- for(auto [c,h]:unko[i]){
- ans+=buf[c].left(h,-1);
- }
- };
- auto addR=[&](int i){
- for(auto [c,h]:unko[i]){
- ans+=buf[c].right(h,1);
- }
- };
- auto delR=[&](int i){
- for(auto [c,h]:unko[i]){
- ans+=buf[c].right(h,-1);
- }
- };
- int block=-1,b=0,e=0;
- for(auto z:qs){
- {
- int cur=pre[z.l]/B;
- if(block!=cur){
- block=cur;
- b=e=lwb(pre,cur*B);
- clear(b);
- }
- }
- while(z.l<b){
- addL(--b);
- }
- while(e<z.r){
- addR(e++);
- }
- while(b<z.l){
- delL(b++);
- }
- while(z.r<e){
- delR(--e);
- }
- res[z.i]+=ans;
- }
- rep(i,m)pr.writeln(res[i]);
- //cerr<<num<<endl;
- }
- signed main(){
- cin.tie(0);
- ios::sync_with_stdio(0);
- cout<<fixed<<setprecision(20);
- //int t;cin>>t;rep(_,t)
- slv();
- }
Advertisement
Add Comment
Please, Sign In to add comment