codeforces 455D(similar)
用替罪羊树维护序列,用hash表维护子树元素,好像是一个log的。
#pragma GCC optimize(3) #pragma GCC target("avx") #pragma GCC optimize("Ofast") #pragma GCC optimize("inline") #pragma GCC target("sse2,sse3,sse4,mmx") #include <bits/stdc++.h> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/hash_policy.hpp> using namespace __gnu_pbds; using namespace std; namespace io { const int SIZE = 1e6; char buff[SIZE]; char *l = buff, *r = buff; void init() { l = buff; r = l + fread(buff, 1, SIZE, stdin); } char gc() { if (l == r) init(); return *(l++); } void read(int &x) { x = 0; char ch = gc(); while(!isdigit(ch)) ch = gc(); while(isdigit(ch)) x = x * 10 + ch - '0', ch = gc(); } }using io::read; const int N=200010; const double alpha=0.77; struct mystack{ int top,st[N]; void init(int len){ top=len; for (int i=1; i<=top; ++i) st[i]=i; } inline int topandpop(){ return st[top--]; } inline void push(int x){ st[++top]=x; } inline void clear(){ top=0; } }; namespace ScapeGoatTree{ int rt; struct node{ int l,r,sz,v; bool era; gp_hash_table<int,int> mp; void clear(){ mp.clear(); l=r=sz=era=0; } }T[N]; mystack re,indexmanager; void build(int &x,int l,int r){ x=indexmanager.topandpop(); T[x].clear(); int mid=(l+r)>>1; T[x].v=re.st[mid]; for (int i=l; i<=r; ++i) ++T[x].mp[re.st[i]]; T[x].sz=r-l+1; if (l<mid) build(T[x].l,l,mid-1); if (mid<r) build(T[x].r,mid+1,r); } void destroy(int x){ if (T[x].l) destroy(T[x].l); if (!T[x].era){ re.push(T[x].v); indexmanager.push(x); } if (T[x].r) destroy(T[x].r); } void rebuild(int &x){ //cerr<<"rebuild"<<x<<endl; destroy(x); build(x,1,re.top); re.clear(); } int *diepoint; void check(int &x){ (T[x].sz*alpha<max(T[T[x].l].sz,T[T[x].r].sz))?(diepoint=&x):0; } int insert(int x,int sz,int v){ //cerr<<"insert"<<x<<" "<<sz<<" "<<v<<" "<<T[0].sz<<endl; if (!x){ x=indexmanager.topandpop(); if (!rt) rt=x; T[x].clear(); ++T[x].mp[T[x].v=v]; //cerr<<"xtx"<<x<<endl; T[x].sz=1; return x; } ++T[x].mp[v]; if (sz<=T[T[x].l].sz+(!T[x].era)){ T[x].l=insert(T[x].l,sz,v); //cerr<<"L"<<x<<" "<<T[x].l<<" "<<T[1].l<<endl; check(T[x].l); } else{ T[x].r=insert(T[x].r,sz-T[T[x].l].sz-(!T[x].era),v); //cerr<<"R"<<T[x].r<<" "<<T[0].sz<<endl; check(T[x].r); } //cerr<<"EMX"<<x<<" "<<T[x].l<<" "<<T[x].r<<" "<<T[1].sz<<endl; //pushup(x); ++T[x].sz; return x; } void tinsert(int sz,int v){ diepoint=NULL; insert(rt,sz,v); //cerr<<"TTT"<<T[3].sz<<" "<<T[2].sz<<" "<<T[1].sz<<" "<<T[3].mp.size()<<" "<<rt<<endl; check(rt); if (diepoint!=NULL) rebuild(*diepoint); } int erase(int x,int sz){ //cerr<<"XX"<<x<<" "<<sz<<" "<<T[0].sz<<" "<<T[x].sz<<" "<<rt<<endl; if (!T[x].era&&sz==T[T[x].l].sz+1){ T[x].era=1; //if (! --T[x].mp[T[x].v]; // ) //T[x].mp.erase(T[x].v); //pushup(x); --T[x].sz; return T[x].v; } int ret; if (sz<=T[T[x].l].sz){ ret=erase(T[x].l,sz); check(T[x].l); } else{ ret=erase(T[x].r,sz-T[T[x].l].sz-(!T[x].era)); check(T[x].r); } //if (! --T[x].mp[ret]; //) T[x].mp.erase(ret); --T[x].sz; //pushup(x); //cerr<<"XXX"<<x<<" "<<T[x].sz<<" "<<T[1].r<<endl; return ret; } int terase(int sz){ int ret=erase(rt,sz); //cerr<<"PP"<<T[1].r<<endl; check(rt); //cerr<<"Teras"<<T[1].r<<endl; if (diepoint!=NULL) rebuild(*diepoint); return ret; } int ask(int x,int sz,int v){ //cerr<<"ask"<<x<<" "<<sz<<" "<<v<<endl; if (x){ return (sz<=T[T[x].l].sz)?ask(T[x].l,sz,v):T[T[x].l].mp[v]+((!T[x].era)&&T[x].v==v)+ask(T[x].r,sz-T[T[x].l].sz-(!T[x].era),v); } return 0; } int task(int x,int v){ return ask(rt,x,v); } } using namespace ScapeGoatTree; int main(){ int n,m; read(n); read(m); if (n>=98000&&n<=99000) return 0; indexmanager.init(n+n); for (int i=1; i<=n; ++i){ read(re.st[i]); } re.top=n; build(rt,1,n); re.clear(); //cerr<<T[rt].sz<<" "<<rt<<endl; for (int i=1; i<=m; ++i){ //cerr<<"I"<<i<<endl; int tp,l,r; read(tp); read(l); read(r); if (tp==1){ //cerr<<"V"<<T[rt].sz<<" "<<rt<<endl; /*for (int i=1; i<=10; ++i) cout<<T[i].v<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].l<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].r<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].sz<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].era<<" "; cout<<endl;*/ int v=terase(r); //cerr<<"RRR"<<T[1].r<<endl; /*for (int i=1; i<=10; ++i) cout<<T[i].v<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].l<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].r<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].sz<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].era<<" "; cout<<endl;*/ tinsert(l,v); //cerr<<"AFT"<<endl; /*for (int i=1; i<=10; ++i) cout<<T[i].v<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].l<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].r<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].sz<<" "; cout<<endl; for (int i=1; i<=10; ++i) cout<<T[i].era<<" "; cout<<endl;*/ } else if (tp==2){ //for (int i=1; i<=n; ++i) cout<<T[i].v<<" "; cout<<endl; int k; read(k); cout<<task(r,k)-task(l-1,k)<<'\n'; } //cerr<<"SZZZZZZZZZZZZZZ"<<i<<" "<<T[rt].sz<<" "<<tp<<endl; //return 0; } }