主席树学习笔记
主席樹學習筆記
說在前邊:
POJ2104
BZOJ1901
- 實現單點修改操作:主席樹的關鍵 - 保存歷史版本,所以顯然不能在已經建好的樹上操作。需要新開一個節點作為這個位置新的根,在這個位置原來的位置上加一條新鏈。這個操作我們在實現靜態前綴和的時候已經掌握了。前綴和時第i棵樹是由第i-1棵樹修改得到的,而修改操作中,新的這棵樹是由它原先這個位置的值修改得到的。他們的本質都是修改操作。
- 實現動態前綴和:T[i]表示樹狀數組中的下表為i代表的區間。利用主席樹維護每個位置,前綴和利用樹狀數組來完成
ZOJ2112
洛谷P3567
BZOJ2588
\(u的值 + v的值 - lca(u,v)的值 - fa[lca(u,v)]的值\), 其他與靜態區間第k大一致。
倍增lca
#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define pb push_back typedef long long ll; const int N = 1e5 + 100; using namespace std; int n,m,a[N]; vector<int> v; int num; int id(int x) {return lower_bound(v.begin(),v.end(),x)-v.begin()+1;} struct edge{int e,nxt;}E[N<<1]; int h[N],cc; void add(int u,int v) {++cc;E[cc].e=v;E[cc].nxt=h[u];h[u]=cc; } int fa[N][20],dep[N]; int lca(int u,int v) {if(dep[u]<dep[v])swap(u,v);for(int i=17;i>=0;--i)if(dep[fa[u][i]]>=dep[v])u=fa[u][i];if(u==v)return u;for(int i=17;i>=0;--i) {if(fa[v][i]!=fa[u][i])v=fa[v][i],u=fa[u][i];}return fa[v][0]; } struct chair_tree{int l,r,num;}T[N*20]; int root[N], tot; void ins(int &rt,int pre,int p,int d,int l,int r) {rt=++tot;T[rt]=T[pre];T[rt].num+=d;if(l==r)return;int mid=(l+r)>>1;if(p<=mid) ins(T[rt].l,T[pre].l,p,d,l,mid);else ins(T[rt].r,T[pre].r,p,d,mid+1,r); } int vis[N]; void build_T() {queue<int> q;q.push(0);vis[0]=1;dep[0]=0;while(!q.empty()) {int u=q.front();q.pop();for(int i=1;i<=17;i++) fa[u][i]=fa[fa[u][i-1]][i-1];for(int i=h[u];~i;i=E[i].nxt) {int v=E[i].e;if(!vis[v]) {vis[v]=1;fa[v][0]=u;dep[v]=dep[u]+1;ins(root[v],root[u],id(a[v]),1,1,num);q.push(v);}}} } int ask(int ur,int vr,int lcar,int lcafr,int k,int l,int r) {if(l==r) return l;int mid=(l+r)>>1,sum=0;sum = T[T[ur].l].num - T[T[lcar].l].num + T[T[vr].l].num - T[T[lcafr].l].num;if(sum>=k) return ask(T[ur].l,T[vr].l,T[lcar].l,T[lcafr].l,k,l,mid);else return ask(T[ur].r,T[vr].r,T[lcar].r,T[lcafr].r,k-sum,mid+1,r); } int main() {scanf("%d%d",&n,&m);rep(i,1,n) scanf("%d",&a[i]),v.pb(a[i]);sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end());num = v.size();memset(h,-1,sizeof(h));rep(i,1,n-1) {int u,v;scanf("%d%d",&u,&v);add(u,v),add(v,u);}a[0]=0; add(0,1),add(1,0);build_T();int lastans=0;rep(ti,1,m) {int x,y,k;scanf("%d%d%d",&x,&y,&k);x^=lastans;lastans = v[ask(root[x],root[y],root[lca(x,y)],root[fa[lca(x,y)][0]],k,1,num)-1];printf("%d\n",lastans);}return 0; }樹剖lca
#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define pb push_back typedef long long ll; const int N = 1e5 + 100; using namespace std; int n,m,a[N]; vector<int> v; int num; int id(int x) {return lower_bound(v.begin(),v.end(),x)-v.begin()+1;} struct chair_tree{int l,r,num;}T[N*50]; int root[N], tot; void ins(int &rt,int pre,int p,int d,int l,int r) {rt=++tot;T[rt]=T[pre];T[rt].num+=d;if(l==r)return;int mid=(l+r)>>1;if(p<=mid) ins(T[rt].l,T[pre].l,p,d,l,mid);else ins(T[rt].r,T[pre].r,p,d,mid+1,r); }struct edge{int e,nxt;}E[N<<1]; int h[N],cc; void add(int u,int v) {++cc;E[cc].e=v;E[cc].nxt=h[u];h[u]=cc; } int dep[N],fa[N],son[N],sz[N],top[N]; void dfs1(int u,int pre,int d) {dep[u]=d;fa[u]=pre;sz[u]=1;for(int i=h[u];~i;i=E[i].nxt) {int v=E[i].e;if(v!=pre) {ins(root[v],root[u],id(a[v]),1,1,num);dfs1(v,u,d+1);sz[u]+=sz[v];if(son[u]==-1||sz[v]>sz[son[u]]) son[u]=v;}} } void dfs2(int u,int sp) {top[u]=sp;if(son[u]==-1)return;dfs2(son[u],sp);for(int i=h[u];~i;i=E[i].nxt) {int v=E[i].e;if(v!=fa[u]&&v!=son[u])dfs2(v,v);} } void init() {memset(son,-1,sizeof(son));dfs1(0,-1,1);dfs2(0,0); } int lca(int u,int v) {while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]])swap(u,v);u=fa[top[u]];}if(dep[u]>dep[v])swap(u,v);return u; } int ask(int ur,int vr,int lcar,int lcafr,int k,int l,int r) {if(l==r) return l;int mid=(l+r)>>1,sum=0;sum = T[T[ur].l].num - T[T[lcar].l].num + T[T[vr].l].num - T[T[lcafr].l].num;if(sum>=k) return ask(T[ur].l,T[vr].l,T[lcar].l,T[lcafr].l,k,l,mid);else return ask(T[ur].r,T[vr].r,T[lcar].r,T[lcafr].r,k-sum,mid+1,r); } int main() {scanf("%d%d",&n,&m);rep(i,1,n) scanf("%d",&a[i]),v.pb(a[i]);sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end());num = v.size();memset(h,-1,sizeof(h));rep(i,1,n-1) {int u,v;scanf("%d%d",&u,&v);add(u,v),add(v,u);}a[0]=0; add(0,1),add(1,0);init();int lastans=0;rep(ti,1,m) {int x,y,k;scanf("%d%d%d",&x,&y,&k);x^=lastans;lastans = v[ask(root[x],root[y],root[lca(x,y)],root[fa[lca(x,y)]],k,1,num)-1];if(ti!=m)printf("%d\n",lastans);else printf("%d",lastans);}return 0; }洛谷P4175
做法1:
#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define pb push_back typedef long long ll; inline int read() {char c=getchar();int x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f; } using namespace std; const int N = 1e5 + 100; struct Q{int a,b,k;}q[N]; struct edge{int e,nxt;}E[N<<1]; int h[N],cc; void add(int u,int v) {++cc;E[cc].e=v;E[cc].nxt=h[u];h[u]=cc;} int n,m,a[N]; vector<int> mp; int num; int id(int x){return lower_bound(mp.begin(),mp.end(),x)-mp.begin()+1;}struct chiarman{int l,r,num;}T[N*200]; int tot,rt[N],rtc[N]; void ins(int &rt,int pre,int p,int d,int l,int r) {rt=++tot;T[rt]=T[pre];T[rt].num+=d;if(l==r)return;int mid=(l+r)>>1;if(p<=mid) ins(T[rt].l,T[pre].l,p,d,l,mid);else ins(T[rt].r,T[pre].r,p,d,mid+1,r); }int dep[N],fa[N],son[N],sz[N],top[N],tid[N],L[N],R[N],pos; void dfs1(int u,int pre,int d) {dep[u]=d;fa[u]=pre;sz[u]=1;for(int i=h[u];~i;i=E[i].nxt) {int v=E[i].e;if(v!=pre) {dfs1(v,u,d+1);sz[u]+=sz[v];if(son[u]==-1||sz[v]>sz[son[u]]) son[u]=v;}} } void dfs2(int u,int sp) {top[u]=sp;L[u]=tid[u]=++pos;if(son[u]==-1)return;dfs2(son[u],sp);for(int i=h[u];~i;i=E[i].nxt) {int v=E[i].e;if(v!=fa[u]&&v!=son[u])dfs2(v,v);}R[u]=pos; } void init_tp() {memset(son,-1,sizeof(son));dfs1(1,0,1);dfs2(1,1); } int lca(int u,int v) {while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]])swap(u,v);u=fa[top[u]];}if(dep[u]>dep[v])swap(u,v);return u; }void build(int u){if(u==-1) return;ins(rt[u],rt[fa[u]],id(a[u]),1,1,num);build(son[u]);for(int i=h[u];~i;i=E[i].nxt)if(E[i].e!=fa[u]&&E[i].e!=son[u]) build(E[i].e); }void B_add(int x,int p,int d){for(int i=x;i<=pos;i+=(i&-i)) ins(rtc[i],rtc[i],p,d,1,num); }vector<int> A,B; int ck(int k) {int sum=0;rep(i,0,A.size()-1)sum+=T[A[i]].num;rep(i,0,B.size()-1)sum-=T[B[i]].num;return (sum>=k); } int qury(int l,int r,int k) {if(l==r)return l;int mid=(l+r)>>1,sum=0;rep(i,0,A.size()-1)sum+=T[T[A[i]].r].num;rep(i,0,B.size()-1)sum-=T[T[B[i]].r].num;if(sum>=k) {rep(i,0,A.size()-1)A[i]=T[A[i]].r;rep(i,0,B.size()-1)B[i]=T[B[i]].r;return qury(mid+1,r,k);}else {rep(i,0,A.size()-1)A[i]=T[A[i]].l;rep(i,0,B.size()-1)B[i]=T[B[i]].l;return qury(l,mid,k-sum);} } int cal() {int sum=0;rep(i,0,A.size()-1)sum+=T[T[A[i]].r].num;rep(i,0,B.size()-1)sum-=T[T[B[i]].r].num;return sum; } void chai(int u,int v) {while(top[u]!=top[v]) {if(dep[top[u]]<dep[top[v]]) swap(u,v);for(int i=tid[u];i;i-=(i&-i))A.pb(rtc[i]);for(int i=tid[top[u]]-1;i;i-=(i&-i))B.pb(rtc[i]);u=fa[top[u]];}if(dep[u]>dep[v])swap(u,v);for(int i=tid[v];i;i-=(i&-i))A.pb(rtc[i]);for(int i=tid[u]-1;i;i-=(i&-i))B.pb(rtc[i]);return ; }void ask(int u,int v,int k) {int p=lca(u,v);A.clear();B.clear();A.pb(rt[u]),A.pb(rt[v]),B.pb(rt[p]),B.pb(rt[fa[p]]);chai(u,v);if(!ck(k)) {puts("invalid request!");return;}printf("%d\n",mp[qury(1,num,k)-1]);return; } int main() {scanf("%d%d",&n,&m);memset(h,-1,sizeof(h));memset(son,-1,sizeof(son));rep(i,1,n) a[i] = read(), mp.pb(a[i]);rep(i,1,n-1) {int u=read(),v=read();add(u,v),add(v,u);}rep(i,1,m) {q[i].k=read(),q[i].a=read(),q[i].b=read();if(q[i].k==0)mp.pb(q[i].b);}sort(mp.begin(),mp.end()); mp.erase(unique(mp.begin(),mp.end()),mp.end());num = mp.size();init_tp();build(1);rep(i,1,m) {if(q[i].k==0) {B_add(tid[q[i].a],id(a[q[i].a]),-1);a[q[i].a]=q[i].b;B_add(tid[q[i].a],id(a[q[i].a]),1);}else {ask(q[i].a,q[i].b,q[i].k);}}return 0; }做法2:
#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define pb push_back typedef long long ll; inline int read() {char c=getchar();int x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f; } using namespace std; const int N = 1e5 + 100; struct Q{int a,b,k;}q[N]; struct edge{int e,nxt;}E[N<<1]; int h[N],cc; void add(int u,int v) {++cc;E[cc].e=v;E[cc].nxt=h[u];h[u]=cc;} int n,m,a[N]; vector<int> mp; int num; int id(int x){return lower_bound(mp.begin(),mp.end(),x)-mp.begin()+1;}struct chiarman{int l,r,num;}T[N*200]; int tot,rt[N],rtc[N]; void ins(int &rt,int pre,int p,int d,int l,int r) {rt=++tot;T[rt]=T[pre];T[rt].num+=d;if(l==r)return;int mid=(l+r)>>1;if(p<=mid) ins(T[rt].l,T[pre].l,p,d,l,mid);else ins(T[rt].r,T[pre].r,p,d,mid+1,r); }int dep[N],fa[N],son[N],sz[N],top[N],tid[N],L[N],R[N],pos; void dfs1(int u,int pre,int d) {dep[u]=d;fa[u]=pre;sz[u]=1;for(int i=h[u];~i;i=E[i].nxt) {int v=E[i].e;if(v!=pre) {dfs1(v,u,d+1);sz[u]+=sz[v];if(son[u]==-1||sz[v]>sz[son[u]]) son[u]=v;}} } void dfs2(int u,int sp) {top[u]=sp;L[u]=tid[u]=++pos;if(son[u]==-1)return;dfs2(son[u],sp);for(int i=h[u];~i;i=E[i].nxt) {int v=E[i].e;if(v!=fa[u]&&v!=son[u])dfs2(v,v);}R[u]=pos; } void init_tp() {memset(son,-1,sizeof(son));dfs1(1,0,1);dfs2(1,1); } int lca(int u,int v) {while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]])swap(u,v);u=fa[top[u]];}if(dep[u]>dep[v])swap(u,v);return u; }void build(int u){if(u==-1) return;ins(rt[u],rt[fa[u]],id(a[u]),1,1,num);build(son[u]);for(int i=h[u];~i;i=E[i].nxt)if(E[i].e!=fa[u]&&E[i].e!=son[u]) build(E[i].e); }void B_add(int x,int p,int d){for(int i=x;i<=pos;i+=(i&-i)) ins(rtc[i],rtc[i],p,d,1,num); }vector<int> A,B; int ck(int k) {int sum=0;rep(i,0,A.size()-1)sum+=T[A[i]].num;rep(i,0,B.size()-1)sum-=T[B[i]].num;return (sum>=k); } int qury(int l,int r,int k) {if(l==r)return l;int mid=(l+r)>>1,sum=0;rep(i,0,A.size()-1)sum+=T[T[A[i]].r].num;rep(i,0,B.size()-1)sum-=T[T[B[i]].r].num;if(sum>=k) {rep(i,0,A.size()-1)A[i]=T[A[i]].r;rep(i,0,B.size()-1)B[i]=T[B[i]].r;return qury(mid+1,r,k);}else {rep(i,0,A.size()-1)A[i]=T[A[i]].l;rep(i,0,B.size()-1)B[i]=T[B[i]].l;return qury(l,mid,k-sum);} } int cal() {int sum=0;rep(i,0,A.size()-1)sum+=T[T[A[i]].r].num;rep(i,0,B.size()-1)sum-=T[T[B[i]].r].num;return sum; } void chai(int u,int v) {while(top[u]!=top[v]) {if(dep[top[u]]<dep[top[v]]) swap(u,v);for(int i=tid[u];i;i-=(i&-i))A.pb(rtc[i]);for(int i=tid[top[u]]-1;i;i-=(i&-i))B.pb(rtc[i]);u=fa[top[u]];}if(dep[u]>dep[v])swap(u,v);for(int i=tid[v];i;i-=(i&-i))A.pb(rtc[i]);for(int i=tid[u]-1;i;i-=(i&-i))B.pb(rtc[i]);return ; }void ask(int u,int v,int k) {int p=lca(u,v);A.clear();B.clear();A.pb(rt[u]),A.pb(rt[v]),B.pb(rt[p]),B.pb(rt[fa[p]]);chai(u,v);if(!ck(k)) {puts("invalid request!");return;}printf("%d\n",mp[qury(1,num,k)-1]);return; } int main() {scanf("%d%d",&n,&m);memset(h,-1,sizeof(h));memset(son,-1,sizeof(son));rep(i,1,n) a[i] = read(), mp.pb(a[i]);rep(i,1,n-1) {int u=read(),v=read();add(u,v),add(v,u);}rep(i,1,m) {q[i].k=read(),q[i].a=read(),q[i].b=read();if(q[i].k==0)mp.pb(q[i].b);}sort(mp.begin(),mp.end()); mp.erase(unique(mp.begin(),mp.end()),mp.end());num = mp.size();init_tp();build(1);rep(i,1,m) {if(q[i].k==0) {B_add(tid[q[i].a],id(a[q[i].a]),-1);a[q[i].a]=q[i].b;B_add(tid[q[i].a],id(a[q[i].a]),1);}else {ask(q[i].a,q[i].b,q[i].k);}}return 0; }BZOJ2212
這個專題就先到這了。。。
轉載于:https://www.cnblogs.com/RRRR-wys/p/9211634.html
總結
- 上一篇: cba门票在哪买 如何订CBA的门票
- 下一篇: Wannafly挑战赛18