BZOJ 1455 左偏树即可
1 #include <cstdio> 2 #define LL long long 3 const LL Maxn=1000100; 4 struct Info{LL l,r,v,Dis;}Tree[Maxn]; 5 LL Father[Maxn],n,m,Dead[Maxn],u,v; 6 inline void Swap(LL &x,LL &y){LL t=x;x=y;y=t;} 7 LL Get(LL x) {return x==Father[x]?x:Father[x]=Get(Father[x]);} 8 LL Merge(LL u,LL v) 9 { 10 if (u==0 || v==0) return u+v; 11 if (Tree[u].v>Tree[v].v) Swap(u,v); 12 Tree[u].r=Merge(Tree[u].r,v); 13 if (Tree[Tree[u].l].Dis<Tree[Tree[u].r].Dis) 14 Swap(Tree[u].l,Tree[u].r); 15 Tree[u].Dis=Tree[Tree[u].l].Dis+1; 16 return u; 17 } 18 int main() 19 { 20 scanf("%lld",&n); 21 for (LL i=1;i<=n;i++) scanf("%lld",&Tree[i].v),Tree[i].l=Tree[i].r=0; 22 for (LL i=1;i<=n;i++) Father[i]=i; 23 scanf("%lld",&m); 24 for (LL i=1;i<=m;i++) 25 { 26 char ch=getchar(); 27 while (ch!='M' && ch!='K') ch=getchar(); 28 if (ch=='M') 29 { 30 scanf("%lld%lld",&u,&v); 31 LL fu=Get(u); 32 LL fv=Get(v); 33 if (fu==fv || Dead[u] || Dead[v]) continue; 34 LL Tmp=Merge(fu,fv); 35 Father[fu]=Father[fv]=Tmp; 36 } 37 if (ch=='K') 38 { 39 scanf("%lld",&u); 40 if (Dead[u]) {puts("0"); continue;} 41 LL fu=Get(u); Dead[fu]=true; 42 printf("%lld\n",Tree[fu].v); 43 LL Tmp=Merge(Tree[fu].l,Tree[fu].r); 44 Father[fu]=Tmp; 45 Father[Tmp]=Tmp; 46 } 47 } 48 return 0; 49 }
BZOJ 1803 用主席树维护Dfs序就可以了
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 const int Maxn=200010; 7 const int Maxm=4010000; 8 inline void Get_Int(int &x) 9 { 10 x=0; register char ch=getchar(); int f=1; 11 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 12 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} x*=f; 13 } 14 inline void Put_Int(int x) 15 { 16 char ch[20]; register int top=0; 17 if (x<0) putchar('-'),x=-x; 18 if (x==0) ch[++top]='0'; 19 while (x) ch[++top]=x%10+'0',x/=10; 20 while (top) putchar(ch[top--]); putchar('\n'); 21 } 22 struct Node {int Sum; Node * l,* r;}; 23 Node Memory[Maxm],*port=Memory,* Root[Maxn],* null; 24 inline void Init() {null=port++;null->Sum=0;null->l=null->r=null;} 25 inline Node* NewNode(Node * last=NULL) 26 { 27 Node * ret=port++; 28 if (last==NULL) {ret->Sum=0; ret->l=ret->r=null;} 29 else {ret->Sum=last->Sum+1; ret->l=last->l; ret->r=last->r;} 30 return ret; 31 } 32 //====================================== 33 int Begin[Maxn],End[Maxn],Dfn[Maxn],head[Maxn]; 34 int cnt,Stamp,u,v,Rank[Maxn],n,C[Maxn],a[Maxn],num; 35 struct Info{int v,id;}Data[Maxn]; 36 struct EDGE{int to,next;}edge[Maxn<<1]; 37 inline bool Cmp(Info A,Info B) {return A.v<B.v;} 38 inline void Add(int u,int v) {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;} 39 void Dfs(int u,int fa) 40 { 41 Dfn[Begin[u]=++Stamp]=u; 42 for (int i=head[u];i!=-1;i=edge[i].next) 43 if (edge[i].to!=fa) Dfs(edge[i].to,u); 44 Dfn[End[u]=++Stamp]=u; 45 } 46 Node * Update(int l,int r,Node *x,int v) 47 { 48 Node * Ret=NewNode(x); 49 if (l==r) return Ret; 50 int mid=(l+r)>>1; 51 if (v<=mid)Ret->l=Update(l,mid,x->l,v); else 52 Ret->r=Update(mid+1,r,x->r,v); 53 return Ret; 54 } 55 void Query(int L,int R,int K) 56 { 57 Node * x=Root[L-1],*y=Root[R]; 58 int P=1,Q=num; 59 while (P!=Q) 60 { 61 int mid=(P+Q)>>1; 62 if (P==Q) 63 { 64 printf("%d\n",C[P]); 65 return; 66 } 67 if (y->l->Sum-x->l->Sum<K) 68 { 69 K-=(y->l->Sum-x->l->Sum); 70 x=x->r,y=y->r; 71 P=mid+1; 72 } else 73 { 74 x=x->l,y=y->l; 75 Q=mid; 76 } 77 } 78 printf("%d\n",C[P]); 79 return; 80 } 81 int main() 82 { 83 // freopen("c.in","r",stdin); 84 scanf("%d",&n); Init(); Root[0]=NewNode(); 85 for (int i=1;i<=n;i++) 86 scanf("%d",&a[i]),Data[i].v=a[i],Data[i].id=i; 87 sort(Data+1,Data+n+1,Cmp); 88 for (int i=1;i<=n;i++) 89 C[++num]=Data[i].id,Rank[Data[i].id]=num; 90 memset(head,-1,sizeof(head)); 91 for (int i=1;i<n;i++) 92 { 93 scanf("%d%d",&u,&v); 94 Add(u,v),Add(v,u); 95 } 96 Dfs(1,0); 97 98 99 for (int i=1;i<=Stamp;i++) 100 Root[i]=Update(1,num,Root[i-1],Rank[Dfn[i]]); 101 int m,x,k; 102 scanf("%d",&m); 103 for (int i=1;i<=m;i++) 104 { 105 scanf("%d%d",&x,&k); k=k*2; 106 Query(Begin[x],End[x],k); 107 } 108 return 0; 109 }
BZOJ 3364 LCA
1 2 #include <cstdio> 3 #include <cstring> 4 const int Maxn=400100; 5 struct EDGE{int to,next,w;}edge[Maxn<<1]; 6 int head[Maxn],Size[Maxn],Dep[Maxn],Top[Maxn],Dis[Maxn],Fa[Maxn],n,m,u,v,w,cnt,Q; 7 inline void Add(int u,int v,int w) {edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt++;} 8 void Dfs1(int u,int fa) 9 { 10 Size[u]=1; 11 for (int i=head[u];i!=-1;i=edge[i].next) 12 { 13 if (edge[i].to==fa) continue; 14 Dep[edge[i].to]=Dep[u]+1; Fa[edge[i].to]=u; 15 Dis[edge[i].to]=Dis[u]+edge[i].w; 16 Dfs1(edge[i].to,u); 17 Size[u]+=Size[edge[i].to]; 18 } 19 } 20 void Dfs2(int u,int fa,int chain) 21 { 22 int k=0; Top[u]=chain; 23 for (int i=head[u];i!=-1;i=edge[i].next) 24 { 25 if (edge[i].to==fa) continue; 26 if (Size[edge[i].to]>Size[k] || k==0) k=edge[i].to; 27 } 28 if (k==0) return; 29 Dfs2(k,u,chain); 30 for (int i=head[u];i!=-1;i=edge[i].next) 31 if (edge[i].to!=fa && edge[i].to!=k) 32 Dfs2(edge[i].to,u,edge[i].to); 33 } 34 int Lca(int u,int v) 35 { 36 while (true) 37 { 38 if (Top[u]==Top[v]) return Dep[u]>Dep[v]?v:u; 39 if (Dep[Top[u]]>Dep[Top[v]]) u=Fa[Top[u]]; else v=Fa[Top[v]]; 40 } 41 } 42 int main() 43 { 44 // freopen("c.in","r",stdin); 45 while (scanf("%d%d",&n,&m)!=EOF) 46 { 47 memset(head,-1,sizeof(head)); 48 char Str[5]; 49 for (int i=1;i<=m;i++) 50 { 51 scanf("%d%d%d%s",&u,&v,&w,Str); 52 Add(u,v,w),Add(v,u,w); 53 } 54 Dep[1]=1; Fa[1]=1; Dis[1]=0; 55 Dfs1(1,0); 56 Dfs2(1,0,1); 57 scanf("%d",&Q); 58 for (int i=1;i<=Q;i++) 59 { 60 scanf("%d%d",&u,&v); 61 printf("%d\n",Dis[u]+Dis[v]-2*Dis[Lca(u,v)]); 62 } 63 } 64 return 0; 65 }
1 #include <cstdio> 2 #include <cstring> 3 const int Maxn=400100; 4 struct EDGE{int to,next,w;}edge[Maxn<<1]; 5 int head[Maxn],Dep[Maxn],Dis[Maxn],Fa[Maxn][20],n,m,u,v,w,cnt,Q; 6 inline void Add(int u,int v,int w) {edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt++;} 7 inline void Swap(int &x,int &y){int t=x;x=y;y=t;} 8 void Dfs(int u,int fa) 9 { 10 for (int i=head[u];i!=-1;i=edge[i].next) 11 { 12 if (edge[i].to==fa) continue; 13 Dep[edge[i].to]=Dep[u]+1; Fa[edge[i].to][0]=u; 14 Dis[edge[i].to]=Dis[u]+edge[i].w; 15 Dfs(edge[i].to,u); 16 } 17 } 18 inline void Init() 19 { 20 for (int i=1;i<=18;i++) 21 for (int j=1;j<=n;j++) Fa[j][i]=Fa[Fa[j][i-1]][i-1]; 22 } 23 inline int Lca(int u,int v) 24 { 25 if (Dep[u]>Dep[v]) Swap(u,v); 26 int Len=Dep[v]-Dep[u]; 27 for (int i=0;i<=18;i++) 28 if (Len&(1<<i)) v=Fa[v][i]; 29 for (int i=18;i>=0;i--) 30 if (Fa[u][i]!=Fa[v][i]) u=Fa[u][i],v=Fa[v][i]; 31 if (u!=v) return Fa[u][0]; 32 return u; 33 } 34 int main() 35 { 36 // freopen("c.in","r",stdin); 37 while (scanf("%d%d",&n,&m)!=EOF) 38 { 39 memset(head,-1,sizeof(head)); 40 char Str[5]; 41 for (int i=1;i<=m;i++) 42 { 43 scanf("%d%d%d%s",&u,&v,&w,Str); 44 Add(u,v,w),Add(v,u,w); 45 } 46 Dep[1]=1; Fa[1][0]=1; Dis[1]=0; 47 Dfs(1,0); Init(); 48 scanf("%d",&Q); 49 for (int i=1;i<=Q;i++) 50 { 51 scanf("%d%d",&u,&v); 52 printf("%d\n",Dis[u]+Dis[v]-2*Dis[Lca(u,v)]); 53 } 54 } 55 return 0;
BZOJ 1699 RMQ
1 #include <cstdio> 2 #include <cmath> 3 const int Maxn=50100; 4 int FMax[Maxn][20],FMin[Maxn][20],n,q,l,r,x; 5 inline int Min(int x,int y) {return x>y?y:x;} 6 inline int Max(int x,int y) {return x>y?x:y;} 7 inline void Init() 8 { 9 for (int i=1;i<=18;i++) 10 for (int j=1;j+(1<<(i-1))<=n;j++) 11 { 12 FMax[j][i]=Max(FMax[j+(1<<(i-1))][i-1],FMax[j][i-1]); 13 FMin[j][i]=Min(FMin[j+(1<<(i-1))][i-1],FMin[j][i-1]); 14 } 15 } 16 inline int Query(int l,int r) 17 { 18 int Len=(int)log2(r-l+1); 19 20 return Max(FMax[l][Len],FMax[r-(1<<Len)+1][Len])-Min(FMin[l][Len],FMin[r-(1<<Len)+1][Len]); 21 } 22 int main() 23 { 24 // freopen("c.in","r",stdin); 25 scanf("%d%d",&n,&q); 26 for (int i=1;i<=n;i++) scanf("%d",&x),FMax[i][0]=x,FMin[i][0]=x; 27 Init(); 28 for (int i=1;i<=q;i++) 29 { 30 scanf("%d%d",&l,&r); 31 printf("%d\n",Query(l,r)); 32 } 33 return 0; 34 }