noip提高組資料結構模板[並查集,st表,樹狀陣列,線段樹]
阿新 • • 發佈:2018-11-04
/*資料結構*/ //並查集 for(int i=1;i<=n;i++) fa[i]=i;*** int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} //st表 for(int i=2;i<=n;i++) Log[i]=Log[i/2]+1; for(int j=1;j<=18;j++) for(int i=1;i<=n;i++) st[i][j]=min(st[i][j-1],st[i+1<<(j-1)][j-1]); int rmq(int l,int r){ int x=Log[r-l+1]; return min(st[l][x],st[r-(1<<x)+1][x]); } //樹狀陣列 void update(int pos,int val){ for(;pos<=n;pos+=pos&-pos) c[pos]+=val; } int quary(int pos){ int ans=0; for(;pos;pos-=pos&-pos) ans+=c[pos]; return ans; } //線段樹 struct Node{int l,r,val,tag;}t[N*4]; void build(int o,int l,int r){ a[o].l=l,a[o].r=r; if(l==r){t[o].val=a[l];return;} int mid=(l+r)>>1; build(o<<1,l,mid),build(o<<1|1,mid+1,r); t[o].val=t[o<<1].val+t[o<<1|1].val; } void spread(int o){ if(t[o].tag){ t[o<<1].val+=t[o].tag*(t[o<<1].r-t[o<<1].l+1); t[o<<1|1].val+=t[o].tag*(t[o<<1|1].r-t[o<<1|1].l+1); t[o<<1].tag+=t[o].tag; t[o<<1|1].tag+=t[o].tag; t[o].tag=0; } } void update(int o,int l,int r,int d){ if(l<=t[o].l&&t[o].r<=r){ t[o].val+=d*(t[o].r-t[o].l+1); t[o].tag+=d;return; } spread(o); int mid=(t[o].l+t[o].r)>>1; if(l<=mid) update(o<<1,l,r,d); if(r>mid) update(o<<1|1,l,r,d); t[o].val=t[o<<1].val+t[o<<1|1].val; } int quary(int o,int l,int r){ if(l<=t[o].l&&t[o].r<=r) return t[o].val; spread(o); int mid=(t[o].l+t[o].r)>>1,ans=0; if(l<=mid) ans+=quary(o<<1,l,r); if(r>mid) ans+=quary(o<<1|1,l,r); return ans; }