zoukankan      html  css  js  c++  java
  • BZOJ 4009: [HNOI2015]接水果 整体二分+DFS序+扫描线

    以前一直以为这道题很恶心,事实证明还好,好多地方脑残写丑了.   

    code:

    #include <cstdio>  
    #include <string> 
    #include <cstring>
    #include <algorithm>           
    #define N 50003  
    using namespace std;  
    void setIO(string s) {
        string in=s+".in"; 
        string out=s+".out"; 
        freopen(in.c_str(),"r",stdin); 
        freopen(out.c_str(),"w",stdout); 
    }   
    namespace BIT { 
        int C[N];   
        int lowbit(int t) {
            return t&(-t); 
        } 
        void update(int x,int v) {
            for(;x<N;x+=lowbit(x)) {
                C[x]+=v; 
            }
        }       
        int query(int x) {
            int tmp=0; 
            for(;x>0;x-=lowbit(x)) {
                tmp+=C[x]; 
            } 
            return tmp; 
        } 
        void clr(int x) {
            for(;x<N;x+=lowbit(x)) {
                C[x]=0; 
            }
        }   
    };                      
    int n,P,Q;   
    int dfn; 
    int edges; 
    int hd[N],to[N<<1],nex[N<<1]; 
    int fa[20][N]; 
    int st[N],ed[N],dep[N];   
    int A[N];                
    int answer[N];     
    struct data {
        int x1; 
        int y1; 
        int x2; 
        int y2;          
        int val; 
        data(int x1=0,int y1=0,int x2=0,int y2=0,int val=0):x1(x1),y1(y1),x2(x2),y2(y2),val(val){}   
    }t[N],tmp1[N],tmp2[N];            
    struct qu {   
        int x,y,id,kth;  
        qu(int x=0,int y=0,int id=0,int kth=0):x(x),y(y),id(id),kth(kth){}     
    }as[N],gl[N],gr[N];     
    struct Seg {
        int x,l,r,d; 
        Seg(int x=0,int l=0,int r=0,int d=0):x(x),l(l),r(r),d(d){}  
    }sg[N];   
    bool cmp_seg(Seg a,Seg b) {               
        return a.x<b.x;  
    }                   
    bool cmp_qu(qu a,qu b) {
        return a.x<b.x;       
    }
    void add(int u,int v) {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;  
    } 
    void dfs(int u,int ff) { 
        fa[0][u]=ff;   
        for(int i=1;i<20;++i) {
            fa[i][u]=fa[i-1][fa[i-1][u]];      
        }     
        st[u]=++dfn;  
        dep[u]=dep[ff]+1;  
        for(int i=hd[u];i;i=nex[i]) { 
            int v=to[i]; 
            if(v==ff) {
                continue; 
            } 
            dfs(v,u);  
        } 
        ed[u]=dfn; 
    }   
    int LCA(int x,int y) {       
        int i,j; 
        if(dep[x]!=dep[y]) { 
            if(dep[x]>dep[y]) {
                swap(x,y);   
            }
            for(i=19;i>=0;--i) {
                if(dep[fa[i][y]]>=dep[x]) {
                    y=fa[i][y];  
                }
            }
        } 
        if(x==y) {
            return x; 
        }   
        for(i=19;i>=0;--i) { 
            if(fa[i][x]!=fa[i][y]) {
                x=fa[i][x]; 
                y=fa[i][y]; 
            }
        } 
        return fa[0][x];  
    }
    int jump(int x,int d) {     
        for(int i=19;i>=0;--i) {   
            if(dep[fa[i][x]]>=d) {
                x=fa[i][x]; 
            }
        }     
        return x;         
    } 
    void solve(int l,int r,int l1,int r1,int L,int R) {            
        if(l>r||l1>r1||L>R) {
            return;   
        }  
        if(l==r) {
            for(int i=L;i<=R;++i) {    
                answer[as[i].id]=l;    
            }          
            return; 
        }   
        int s=0;      
        int mid=(l+r)>>1; 
        int cn1=0,cn2=0; 
        int as1=0,as2=0;   
        for(int i=l1;i<=r1;++i) {   
            if(t[i].val<=mid) {
                tmp1[++cn1]=t[i];              // 是左面的  
                sg[++s]=Seg(t[i].x1,t[i].x2,t[i].y2,1);   
                sg[++s]=Seg(t[i].y1+1,t[i].x2,t[i].y2,-1);                      
            }
            else {
                tmp2[++cn2]=t[i];  
            }
        }                        
        sort(sg+1,sg+1+s,cmp_seg);         
        int j=1;    
        for(int i=L;i<=R;++i) {   
            while(j<=s&&sg[j].x<=as[i].x) {
                BIT::update(sg[j].l,sg[j].d);   
                BIT::update(sg[j].r+1,sg[j].d*-1);              
                ++j;   
            }
            int tmp=BIT::query(as[i].y);                  
            if(tmp>=as[i].kth) {
                gl[++as1]=as[i];            
            }                
            else {
                as[i].kth-=tmp;   
                gr[++as2]=as[i];  
            }
        }                                     
        for(int i=1;i<=s;++i) {
            BIT::clr(sg[i].l);    
            BIT::clr(sg[i].r+1);      
        }                 
        int pos=l1;   
        for(int i=1;i<=cn1;++i) {
            t[pos++]=tmp1[i];  
        } 
        for(int i=1;i<=cn2;++i) {
            t[pos++]=tmp2[i];   
        }    
        pos=L;   
        for(int i=1;i<=as1;++i) {
            as[pos++]=gl[i]; 
        }
        for(int i=1;i<=as2;++i) {
            as[pos++]=gr[i]; 
        }                          
        solve(l,mid,l1,l1+cn1-1,L,L+as1-1);    
        solve(mid+1,r,l1+cn1,r1,L+as1,R);           
    }
    int main() { 
        // setIO("input");  
        int i,j,t1=0; 
        scanf("%d%d%d",&n,&P,&Q);    
        for(i=1;i<n;++i) { 
            int x,y; 
            scanf("%d%d",&x,&y); 
            add(x,y); 
            add(y,x); 
        }   
        dfs(1,0);        
        for(i=1;i<=P;++i) {       
            int u,v,c; 
            scanf("%d%d%d",&u,&v,&c);          
            A[i]=c;     
            int lca=LCA(u,v);    
            if(lca!=u&&lca!=v) {  
                if(st[u]>st[v]) {
                    swap(u,v);   
                }             
                t[++t1]=data(st[u],ed[u],st[v],ed[v],c);        
            }
            else { 
                if(lca==u) {
                    swap(u,v); 
                }    
                int w=jump(u,dep[v]+1);                        
                if(st[w]-1>=1) {
                    t[++t1]=data(1,st[w]-1,st[u],ed[u],c);   
                }
                if(ed[w]+1<=n) {
                    t[++t1]=data(st[u],ed[u],ed[w]+1,n,c);          
                }
            }
        }   
        sort(A+1,A+1+P);  
        int cnt=unique(A+1,A+1+P)-A-1;        
        for(i=1;i<=t1;++i) {  
            t[i].val=lower_bound(A+1,A+1+cnt,t[i].val)-A;                            
        }                         
        for(i=1;i<=Q;++i) { 
            int x,y,z;  
            scanf("%d%d%d",&x,&y,&z);         
            if(st[x]>st[y]) {
                swap(x,y); 
            }                                                          
            as[i]=qu(st[x],st[y],i,z);           
        }                                 
        sort(as+1,as+1+Q,cmp_qu);  
        solve(1,cnt,1,t1,1,Q);                
        for(i=1;i<=Q;++i) {
            printf("%d
    ",A[answer[i]]);  
        }      
        return 0; 
    }                
    

      

  • 相关阅读:
    导航
    占位
    django(一)
    进程与线程
    网络编程
    反射 单例模式
    面向对象及命名空间
    logging,包
    模块(二)os hashlib
    装饰器&递归
  • 原文地址:https://www.cnblogs.com/guangheli/p/12077185.html
Copyright © 2011-2022 走看看