打印2
数据结构
普通堆、可删堆
struct Node{
inline int operator < (const Node &o){}
_inline int operator == (const Node &o){}
};
inline void swap(Node &a,Node &b){}
struct Heap{
Node a[N];
int size;
inline void push(const Node &x){
int i=++size,fa;a[size]=x;
while(i>1){
fa=i>>1;
if(a[fa]<a[i]) return;
swap(a[fa],a[i]);i=fa;
}
}
inline void pop(){
int i=1,ls,rs;a[1]=a[size--];
while((i<<1)<=size){
ls=i<<1;rs=ls|1;
if(rs<=size&&a[rs]<a[ls]) ls=rs;
if(a[i]<a[ls]) return;
swap(a[ls],a[i]);i=ls;
}
}
};
struct DeletableHeap{
Heap ins,dele;
inline Node top(){while(dele.size&&ins.a[1]==dele.a[1]) ins.pop(),dele.pop();return ins.a[1];}
inline void pop(){while(dele.size&&ins.a[1]==dele.a[1]) ins.pop(),dele.pop();ins.pop();}
inline void push(const Node &x){ins.push(x);}
inline void del(const Node &x){dele.push(x);}
inline void clear(){ins.size=dele.size=0;}
inline int size(){return ins.size-dele.size;}
inline int empty(){return ins.size==dele.size;}
};
使用自定义函数重载 std::set
,std::priority_queue
等的比较
inline int pqueCmp(const int &a,const int &b){return a>b;}
std::priority_queue<int,std::vector<int>,int(*)(const int &a,const int &b)>pque(pqueCmp);
树状数组
int tree[N];
#define lowbit(x) (x&(-x))
inline void add(int pos,int k){for(;pos<=n;pos+=lowbit(pos)) tree[pos]+=k;}
inline int ask(int pos){
int ans=0;
for(;pos;pos-=lowbit(pos)) ans+=tree[pos];
return ans;
}
线段树合并、分裂
Node* merge(Node *a,Node *b,int l,int r){
if(a==null) return b;
if(b==null) return a;
if(l==r) return a->cnt+=b->cnt,a;
int mid=(l+r)>>1;
a->ls=merge(a->ls,b->ls,l,mid);a->rs=merge(a->rs,b->rs,mid+1,r);
pushup(a);return a;
}
void split(Node *&a,Node *&b,int l,int r,int ql,int qr){
if(a==null) return;
if(ql<=l&&r<=qr) return b=a,a=null,void();
if(b==null) New(b);
int mid=(l+r)>>1;
if(ql<=mid) split(a->ls,b->ls,l,mid,ql,qr);
if(qr>mid) split(a->rs,b->rs,mid+1,r,ql,qr);
pushup(a);pushup(b);
}
替罪羊树
#define alpha 0.7
struct Node{
Node *ls,*rs;
int val,cnt,size;//size:num of not deleted,cnt:all
int deleted;
inline void pushup(){}
}*null,*root,*nodes[1100005],**badtag;
int nodeNum;
inline int isbad(Node *tree){return tree->ls->cnt>alpha*tree->cnt+5||tree->rs->cnt>alpha*tree->cnt+5;}
void dfs(Node *tree){
if(tree==null) return;
dfs(tree->ls);
if(!tree->deleted) nodes[++nodeNum]=tree;
dfs(tree->rs);
if(tree->deleted) delete tree;
}
Node *build(int l,int r){
if(l>r) return null;
if(l==r){
nodes[l]->ls=nodes[l]->rs=null;
nodes[l]->cnt=nodes[l]->size=1;
return nodes[l];
}
int mid=(l+r)>>1;
Node *tree=nodes[mid];
tree->ls=build(l,mid-1);tree->rs=build(mid+1,r);
tree->pushup();
return tree;
}
inline void rebuild(Node *&tree){
nodeNum=0;
dfs(tree);
tree=build(1,nodeNum);
}
void insert(Node *&tree,int x){
if(tree==null){
tree=new Node;
tree->ls=tree->rs=null;
tree->deleted=0;tree->val=x;
tree->size=tree->cnt=1;
return;
}
tree->size++;tree->cnt++;
if(x>tree->val) insert(tree->rs,x);
else insert(tree->ls,x);
if(isbad(tree)) badtag=&tree;
}
inline void Insert(Node *&tree,int x){
badtag=&null;
insert(tree,x);
if(badtag!=&null) rebuild(*badtag);
}
inline int rank(Node *tree,int x){
int ans=1;
while(tree!=null){
if(x<=tree->val) tree=tree->ls;
else{
ans+=tree->ls->size+!tree->deleted;
tree=tree->rs;
}
}
return ans;
}
inline int kth(tr *tree,int rk){
while(tree!=null){
if(!tree->deleted&&tree->ls->size+1==rk) return tree->val;
if(rk<=tree->ls->size) tree=tree->ls;
else{
rk-=tree->ls->size+!tree->deleted;
tree=tree->rs;
}
}
}
void erase(tr *tree,int rk){
if(!tree->deleted&&rk==tree->ls->size+1){
tree->deleted=1;
tree->size--;
return;
}
tree->size--;
if(rk<=tree->ls->size+!tree->deleted) erase(tree->ls,rk);
else erase(tree->rs,rk-tree->ls->size-!tree->deleted);
}
fhq-treap
struct Node{
Node *ls,*rs;
int val,rnd,size;
inline void pushup(){size=1+ls->size+rs->size;}
}*root,*null;
inline void init(Node *x){x->ls=x->rs=null;x->size=1;x->rnd=rand();}
inline void init(){
srand(822);
null=new Node;null->ls=null->rs=null;null->size=0;null->val=INT_INF;
root=null;
}
void split(Node *tree,int k,Node *&L,Node *&R){
if(tree==null) return L=R=null,void();
if(tree->ls->size>=k){
R=tree;
split(tree->ls,k,L,R->ls);
R->pushup();
}
else{
L=tree;
split(tree->rs,k-tree->ls->size-1,L->rs,R);
L->pushup();
}
}
Node* merge(Node *L,Node *R){
if(L==null) return R;
if(R==null) return L;
if(L->rnd<R->rnd){
L->rs=merge(L->rs,R);
return L->pushup(),L;
}
else{
R->ls=merge(L,R->ls);
return R->pushup(),R;
}
}
inline int rank(int val){
int ans=1;
Node *tree=root;
while(tree!=null){
if(val<=tree->val) tree=tree->ls;
else{
ans+=tree->ls->size+1;
tree=tree->rs;
}
}
return ans;
}
inline void insert(int val){
int rk=rank(val)-1;
Node *x,*y;
split(root,rk,x,y);
Node *a=new Node;init(a);a->val=val;
root=merge(merge(x,a),y);
}
inline void del(int val){
int rk=rank(val);
Node *x,*y,*z;
split(root,rk,x,z);
split(x,rk-1,x,y);//y->val=val,y->size=1
root=merge(x,z);
delete y;
}
inline int kth(int k){
Node *x,*y,*z;
split(root,k-1,x,y);
split(y,1,y,z);
root=merge(x,merge(y,z));
return y->val;
}
link-cut-tree
struct LCT{
struct Node{
Node *son[2],*fa;
int val,res;
int tag;
}addr_[N],*null,*addr;
inline void init(){addr=addr_;null=addr;}
#define ident(tree,fa) (fa->son[1]==tree)
#define notroot(tree) (tree->fa->son[0]==tree||tree->fa->son[1]==tree)
#define pushup(tree) (tree->res=tree->son[0]->res^tree->son[1]->res^tree->val)
inline void connect(Node *tree,Node *fa,int k){fa->son[k]=tree;tree->fa=fa;}
inline void pushdown(Node *tree){
if(!tree->tag) return;
tree->tag=0;
tree->son[0]->tag^=1;tree->son[1]->tag^=1;
std::swap(tree->son[0],tree->son[1]);
}
inline void rotate(Node *tree){
Node *fa=tree->fa,*faa=fa->fa;
pushdown(fa);pushdown(tree);
int k=ident(tree,fa);
connect(tree->son[k^1],fa,k);
tree->fa=faa;
if(notroot(fa)) faa->son[ident(fa,faa)]=tree;
connect(fa,tree,k^1);
pushup(fa);pushup(tree);
}
inline void splay(Node *tree){
Node *fa=tree->fa,*faa=fa->fa;
while(notroot(tree)){
fa=tree->fa;faa=fa->fa;
if(notroot(fa)) rotate((ident(tree,fa)^ident(fa,faa))?tree:fa);
rotate(tree);
}
}
inline void access(Node *x){
for(Node *lastx=null;x!=null;lastx=x,x=x->fa){
pushdown(x);splay(x);x->son[1]=lastx;pushup(x);
}
}
inline void makeroot(Node *x){access(x);splay(x);x->tag^=1;}
inline Node* findroot(Node *x){
access(x);splay(x);pushdown(x);
while(x->son[0]!=null) x=x->son[0],pushdown(x);
splay(x);return x;
}
inline void link(Node *x,Node *y){makeroot(x);if(findroot(y)!=x) x->fa=y;}
inline void cut(Node *x,Node *y){
makeroot(x);
if(findroot(y)!=x||y->fa!=x||y->son[0]!=null) return;
y->fa=x->son[1]=null;pushup(x);
}
inline Node* split(Node *x,Node *y){makeroot(x);access(y);splay(y);return y;}
inline Node* Split(int x,int y){return split(addr+x,addr+y);}
inline void link(int x,int y){link(addr+x,addr+y);}
inline void cut(int x,int y){cut(addr+x,addr+y);}
inline void change(int o,int val){Node *x=addr+o;splay(x);x->val=val;pushup(x);}
};
树分块
void dfs(int u,int last=0){
deep[u]=deep[fa[0][u]]+1;
for(int j=1;j<=LOG_N;j++) fa[j][u]=fa[j-1][fa[j-1][u]];
if(keyId[u]){
lastKey[u]=last;
int lastid=keyId[last];set[keyId[u]][lastid].resize(N);set[keyId[u]][lastid].reset();
for(int i=u;i^last;i=fa[0][i]) set[keyId[u]][lastid].set(id[i],1);
for(int i=lastKey[last];i;i=lastKey[i]){
set[keyId[u]][keyId[i]].resize(N);
set[keyId[u]][keyId[i]]=set[keyId[u]][lastid]|set[lastid][keyId[i]];
}
last=u;
}
for(int i=G.fir[u];i;i=G.nex[i])if(G.to[i]^fa[0][u]) fa[0][G.to[i]]=u,dfs(G.to[i],last);
}
inline int getLca(int u,int v){
if(deep[u]<deep[v]) lib::swap(u,v);
for(int j=LOG_N;~j;j--)if(deep[fa[j][u]]>=deep[v]) u=fa[j][u];
if(u==v) return u;
for(int j=LOG_N;~j;j--)if(fa[j][u]^fa[j][v]) u=fa[j][u],v=fa[j][v];
return fa[0][u];
}
inline void pre(int n){
static int oo[N];
for(int i=1;i<=n;i++) oo[i]=i;
srand(822);
std::random_shuffle(oo+1,oo+1+n);
for(int i=1,cntKey=0,o=lib::min(n,BN);i<=o;i++) keyId[oo[i]]=++cntKey;
std::sort(oo+1,oo+1+n,[](const int &a,const int &b){return val[a]<val[b];});
for(int o=0,i=1;i<=n;i++){
if(val[oo[i]]!=val[oo[i-1]]||i==1) o++;
id[oo[i]]=o;
}
dfs(1);
}
while(m--){
while(!keyId[u]&&(u^lca)) u=fa[0][u];
while(!keyId[v]&&(v^lca)) v=fa[0][v];
int blockId=keyId[u];
while(deep[lastKey[u]]>=deep[lca]) u=lastKey[u];
blockId=keyId[v];
while(deep[lastKey[v]]>=deep[lca]) v=lastKey[v];
while(u^lca) u=fa[0][u];
while(v^lca) v=fa[0][v];
}
bitset
struct Bitset{
#define W 63
unsigned long long *a;
int size;
inline Bitset(){size=0;}
inline ~Bitset(){if(size) delete []a;}
inline void resize(const int &s){
if(size) delete []a;
size=(s+W)>>6;
a=new unsigned long long[size];
}
inline void reset(){__builtin_memset(a,0,size*sizeof(a[0]));}
inline void set(){__builtin_memset(a,255,size*sizeof(a[0]));}
inline int operator [] (const int &pos)const{return (a[pos>>6]>>(pos&W))&1;}
inline void operator = (const Bitset &o){resize(o.size<<6);__builtin_memcpy(a,o.a,size*sizeof(a[0]));}
inline void set(const int &pos,const int &val){
a[pos>>6]&=~(1ull<<(pos&W));a[pos>>6]|=((unsigned long long)val<<(pos&W));}
}
inline int count(){
int ans=0;
for(int i=0;i<size;i++) ans+=__builtin_popcountll(a[i]);
return ans;
}
inline Bitset operator ^ (const Bitset &o)const{
Bitset ans;ans=*this;
for(int i=0;i<size;i++) ans.a[i]^=o.a[i];
return ans;
}
inline Bitset operator | (const Bitset &o)const{
Bitset ans;ans=*this;
for(int i=0;i<size;i++) ans.a[i]|=o.a[i];
return ans;
}
inline Bitset operator & (const Bitset &o)const{
Bitset ans;ans=*this;
for(int i=0;i<size;i++) ans.a[i]&=o.a[i];
return ans;
}
inline void operator ^= (const Bitset &o){for(int i=0;i<size;i++) a[i]^=o.a[i];}
inline void operator |= (const Bitset &o){for(int i=0;i<size;i++) a[i]|=o.a[i];}
inline void operator &= (const Bitset &o){for(int i=0;i<size;i++) a[i]&=o.a[i];}
inline Bitset operator ~ ()const{
Bitset ans;ans=*this;
for(int i=0;i<size;i++) ans.a[i]=~ans.a[i];
return ans;
}
inline Bitset operator >> (int bit){
Bitset ans;ans=*this;
int o=bit>>6;bit&=W;
if(o) for(int i=0;i+o<size;i++) ans.a[i]=a[i+o];
for(int i=size-o;i<size;i++) ans.a[i]=0;
if(!bit) return ans;
int S=(1ull<<bit)-1;
for(int i=0;i<size-1;i++) ans.a[i]>>=bit,ans.a[i]|=(ans.a[i+1]&S)<<(W+1-bit);
ans.a[size-1]>>=bit;
return ans;
}
#undef W
};
双模哈希
#define HASH_MOD1 1000000007
#define HASH_MOD2 1000000009
#define HASH_BASE 822
struct Hash{
unsigned long long a,b;
inline void operator = (const unsigned long long &o){a=b=o;}
inline Hash operator + (const Hash &o){return (Hash){(a+o.a)%HASH_MOD1,(b+o.b)%HASH_MOD2};}
inline Hash operator - (const Hash &o){return (Hash){(a-o.a+HASH_MOD1)%HASH_MOD1,(b-o.b+HASH_MOD2)%HASH_MOD2};}
inline Hash operator * (const unsigned long long &o){return (Hash){a*o%HASH_MOD1,b*o%HASH_MOD2};}
inline int operator == (const Hash &o){return a==o.a&&b==o.b;}
inline int operator != (const Hash &o){return a!=o.a||b!=o.b;}
inline int operator < (const Hash &o)const{return a==o.a?b<o.b:a<o.a;}
inline unsigned __int128 toUint128(){return (unsigned __int128)a*_ULL_MAX+b;}
};