BZOJ 3545ONTAK 2010Peaks & BZOJ 3551ONTAK 2010Peaks加强版 Kruskal重构树

Posted abclzr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3545ONTAK 2010Peaks & BZOJ 3551ONTAK 2010Peaks加强版 Kruskal重构树相关的知识,希望对你有一定的参考价值。

sunshine的A题我竟然调了一周!!!

把循环dfs改成一个dfs就可以,,,我也不知道为什么这样就不会RE,但它却是A了,,,

这周我一直在调这个题,总结一下智障错误:

1.倍增的范围设成了n而不是n*2-1,,,

2.重构树的顶点是n*2-1,而我一开始设成了n,,,

3.define里的for3和for4的i--打成i++,,,,,,,,,,,,

4.dfs爆栈了,找CA爷问的编译命令里手动扩栈,真是愚蠢的问题,,,,

比赛时绝不会有太多时间,在这么犯逗就得滚粗了QAQ

3545:

#include<cstdio> 
#include<cstring> 
#include<algorithm> 
#define for1(i,a,n) for(int i=(a);i<=(n);i++) 
#define for2(i,a,n) for(int i=(a);i<(n);i++) 
#define for3(i,a,n) for(int i=(a);i>=(n);i--) 
#define for4(i,a,n) for(int i=(a);i>(n);i--) 
#define CC(i,a) memset(i,a,sizeof(i)); 
#define read(x) x=getint() 
using namespace std; 
inline const int getint(){char c=getchar();int k=1,r=0;for(;c<‘0‘||c>‘9‘;c=getchar())if(c==‘-‘)k=-1;for(;c>=‘0‘&&c<=‘9‘;c=getchar())r=r*10+c-‘0‘;return k*r;} 
inline const int max(const int &a,const int &b){return a>b?a:b;} 
inline const int min(const int &a,const int &b){return a<b?a:b;} 
const int N=1E5+10; 
const int M=5*1E5+10; 
struct node{int x,y,z;}E[M]; 
struct snnn{int l,r,s;}T[N*30]; 
int n,m,fa[N<<1],num[N<<1],HH[N],id[N],H[N],cnt,f[N<<1][20]; 
int root[N],L[N<<1],R[N<<1],lch[N<<1],rch[N<<1],ST[N]; 
inline bool cmp(node X,node Y){return X.z<Y.z;} 
inline bool cmp2(int X,int Y){return HH[X]<HH[Y];} 
inline void init(){CC(fa,0);CC(num,0);CC(HH,0);CC(id,0);CC(H,0);CC(f,0);CC(root,0);CC(L,0);CC(R,0);CC(lch,0);CC(rch,0);CC(ST,0);} 
inline int find(int x){ 
    if (x==fa[x]) return x; 
    else{fa[x]=find(fa[x]);return fa[x];} 
} 
inline void LCA(int dd){ 
    for1(j,1,19) 
        for1(i,1,dd) 
            f[i][j]=f[f[i][j-1]][j-1]; 
} 
inline void dfs(int x){ 
    if (lch[x]&&rch[x]){ 
        L[x]=cnt+1; 
        dfs(lch[x]); 
        dfs(rch[x]); 
        R[x]=cnt; 
    }else{ 
        cnt++; ST[cnt]=x; 
        L[x]=cnt; R[x]=cnt; 
    } 
} 
inline void update(int l,int r,int &pos,int key){ 
    T[++cnt]=T[pos]; pos=cnt; T[pos].s++; 
    if (l==r) return; 
    int mid=(l+r)>>1; 
    if (key<=mid) update(l,mid,T[pos].l,key); else update(mid+1,r,T[pos].r,key); 
} 
inline int LCA_find(int x,int y){ 
    for3(i,19,0) 
     if ((f[x][i]!=0)&&(num[f[x][i]]<=y)) 
      x=f[x][i]; 
    return x; 
} 
inline int query(int LL,int RR,int key){ 
    int mid,s,x=root[LL],y=root[RR],l=1,r=n; 
    while (l<r){ 
        mid=(l+r)>>1; s=T[T[y].l].s-T[T[x].l].s; 
        if (key<=s) r=mid,x=T[x].l,y=T[y].l; 
        else l=mid+1,key-=s,x=T[x].r,y=T[y].r; 
    }return l; 
} 
int main(){
    init(); 
    read(n); read(m); int Q; read(Q); 
    for1(i,1,n) read(HH[i]),id[i]=i; 
    sort(id+1,id+n+1,cmp2); 
    for1(i,1,n) H[id[i]]=i; 
    for1(i,1,m){read(E[i].x);read(E[i].y);read(E[i].z);} 
    sort(E+1,E+m+1,cmp); 
    cnt=n+1; 
    for2(i,1,n<<1) fa[i]=i; 
    for1(i,1,m){ 
        int fx=find(E[i].x),fy=find(E[i].y); 
        if (fx!=fy){ 
            fa[fx]=cnt; fa[fy]=cnt; 
            f[fx][0]=cnt; f[fy][0]=cnt; 
            lch[cnt]=fx; rch[cnt]=fy; 
            num[cnt]=E[i].z; 
            cnt++; 
            if (cnt>((n<<1)-1)) break; 
        } 
    } 
    int dd=cnt-1; 
    LCA(dd); 
    cnt=0; 
    //for2(i,1,n<<1) if (L[i]==0) dfs(find(i)); 
    dfs(dd);
    cnt=0; 
    for1(i,1,n){ 
        root[i]=root[i-1]; 
        update(1,n,root[i],H[ST[i]]); 
    } 
    int a,b,c,la=0; 
    for1(i,1,Q){ 
        read(a); read(b); read(c); 
        //a^=la; b^=la; c^=la; 
        int rt=LCA_find(a,b),nn; 
        if (R[rt]-L[rt]+1<c) nn=-1; 
        else nn=HH[id[query(L[rt]-1,R[rt],R[rt]-L[rt]+2-c)]],la=nn; 
        printf("%d\n",nn); 
    }
    return 0; 
}

3551:

#include<cstdio> 
#include<cstring> 
#include<algorithm> 
#define for1(i,a,n) for(int i=(a);i<=(n);i++) 
#define for2(i,a,n) for(int i=(a);i<(n);i++) 
#define for3(i,a,n) for(int i=(a);i>=(n);i--) 
#define for4(i,a,n) for(int i=(a);i>(n);i--) 
#define CC(i,a) memset(i,a,sizeof(i)); 
#define read(x) x=getint() 
using namespace std; 
inline const int getint(){char c=getchar();int k=1,r=0;for(;c<‘0‘||c>‘9‘;c=getchar())if(c==‘-‘)k=-1;for(;c>=‘0‘&&c<=‘9‘;c=getchar())r=r*10+c-‘0‘;return k*r;} 
inline const int max(const int &a,const int &b){return a>b?a:b;} 
inline const int min(const int &a,const int &b){return a<b?a:b;} 
const int N=1E5+10; 
const int M=5*1E5+10; 
struct node{int x,y,z;}E[M]; 
struct snnn{int l,r,s;}T[N*30]; 
int n,m,fa[N<<1],num[N<<1],HH[N],id[N],H[N],cnt,f[N<<1][20]; 
int root[N],L[N<<1],R[N<<1],lch[N<<1],rch[N<<1],ST[N]; 
inline bool cmp(node X,node Y){return X.z<Y.z;} 
inline bool cmp2(int X,int Y){return HH[X]<HH[Y];} 
inline void init(){CC(fa,0);CC(num,0);CC(HH,0);CC(id,0);CC(H,0);CC(f,0);CC(root,0);CC(L,0);CC(R,0);CC(lch,0);CC(rch,0);CC(ST,0);} 
inline int find(int x){ 
    if (x==fa[x]) return x; 
    else{fa[x]=find(fa[x]);return fa[x];} 
} 
inline void LCA(int dd){ 
    for1(j,1,19) 
        for1(i,1,dd) 
            f[i][j]=f[f[i][j-1]][j-1]; 
} 
inline void dfs(int x){ 
    if (lch[x]&&rch[x]){ 
        L[x]=cnt+1; 
        dfs(lch[x]); 
        dfs(rch[x]); 
        R[x]=cnt; 
    }else{ 
        cnt++; ST[cnt]=x; 
        L[x]=cnt; R[x]=cnt; 
    } 
} 
inline void update(int l,int r,int &pos,int key){ 
    T[++cnt]=T[pos]; pos=cnt; T[pos].s++; 
    if (l==r) return; 
    int mid=(l+r)>>1; 
    if (key<=mid) update(l,mid,T[pos].l,key); else update(mid+1,r,T[pos].r,key); 
} 
inline int LCA_find(int x,int y){ 
    for3(i,19,0) 
     if ((f[x][i]!=0)&&(num[f[x][i]]<=y)) 
      x=f[x][i]; 
    return x; 
} 
inline int query(int LL,int RR,int key){ 
    int mid,s,x=root[LL],y=root[RR],l=1,r=n; 
    while (l<r){ 
        mid=(l+r)>>1; s=T[T[y].l].s-T[T[x].l].s; 
        if (key<=s) r=mid,x=T[x].l,y=T[y].l; 
        else l=mid+1,key-=s,x=T[x].r,y=T[y].r; 
    }return l; 
} 
int main(){
    init(); 
    read(n); read(m); int Q; read(Q); 
    for1(i,1,n) read(HH[i]),id[i]=i; 
    sort(id+1,id+n+1,cmp2); 
    for1(i,1,n) H[id[i]]=i; 
    for1(i,1,m){read(E[i].x);read(E[i].y);read(E[i].z);} 
    sort(E+1,E+m+1,cmp); 
    cnt=n+1; 
    for2(i,1,n<<1) fa[i]=i; 
    for1(i,1,m){ 
        int fx=find(E[i].x),fy=find(E[i].y); 
        if (fx!=fy){ 
            fa[fx]=cnt; fa[fy]=cnt; 
            f[fx][0]=cnt; f[fy][0]=cnt; 
            lch[cnt]=fx; rch[cnt]=fy; 
            num[cnt]=E[i].z; 
            cnt++; 
            if (cnt>((n<<1)-1)) break; 
        } 
    } 
    int dd=cnt-1; 
    LCA(dd); 
    cnt=0; 
    //for2(i,1,n<<1) if (L[i]==0) dfs(find(i)); 
    dfs(dd);
    cnt=0; 
    for1(i,1,n){ 
        root[i]=root[i-1]; 
        update(1,n,root[i],H[ST[i]]); 
    } 
    int a,b,c,la=0; 
    for1(i,1,Q){ 
        read(a); read(b); read(c); 
        a^=la; b^=la; c^=la; 
        int rt=LCA_find(a,b),nn; 
        if (R[rt]-L[rt]+1<c) nn=-1,la=0;
        else nn=HH[id[query(L[rt]-1,R[rt],R[rt]-L[rt]+2-c)]],la=nn; 
        printf("%d\n",nn); 
    }
    return 0; 
}

 然后就可以了O(∩_∩)O~~

以上是关于BZOJ 3545ONTAK 2010Peaks & BZOJ 3551ONTAK 2010Peaks加强版 Kruskal重构树的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3545ONTAK 2010Peaks & BZOJ 3551ONTAK 2010Peaks加强版 Kruskal重构树

[BZOJ3545][ONTAK2010]Peaks

bzoj3545[ONTAK2010]Peaks 线段树合并

Bzoj3545 [ONTAK2010]Peaks

bzoj3545: [ONTAK2010]Peaks 主席树合并

bzoj 3545/3551: [ONTAK2010]Peaks -- 主席树,最小生成树,倍增