• BZOJ4009 [HNOI2015]接水果


    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=4009

    打了一会儿的整体二分了...于是就准备好了做这道题。

    具体题解不想讲了,看看别人的就好:http://blog.csdn.net/thy_asdf/article/details/50363672

    然后注意二维平面上其实我们是舍弃了一部分点的,就是类似要求横坐标一定要小于纵坐标这种...这样就不会算重或者算漏了...

    上面这个的代码 就是if(x>y) swap(x,y)?...好吧诸如此类..

    敲了比较久,感觉比较顺,结果发现样例都不能过?!然后我检查很久觉得二分没错之后,调试啊调试,检查啊检查,结果发现原来是树状数组的区间加减打挂了[以前都是打线段树,不过今天觉得树状数组常数这么小,还是要复习一下的吧...结果一打就挂...],后来发现是单点修改,所以只要一个简单的差分就好了...改完之后就A了

    不过复杂度貌似和同机房的同学不一样?...我的是二分答案,他们的说是二分选哪个篮子,其实相当于离散化?...

    反正最后他们的快一些...不过感觉我这个模板感觉很靠谱,我就不改了...反正复杂度是能过的就行了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    inline int in(){
        int x=0;char ch=getchar();
        while(ch>'9' || ch<'0') ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return x;
    }
    
    const int maxn=40010;
    const int INF=0x3f3f3f3f;
    
    struct Node{
        int data,next;
    }node[maxn<<1];
    
    #define now node[point].data
    #define then node[point].next
    
    struct Query{
        int tp,x,y,k,cur,rk;
    }q[maxn*6],q1[maxn*6],q2[maxn*6];
    
    int n,m,P,Idex;
    int tot,cnt;
    int b[maxn];
    int tmp[maxn*6],ans[maxn];
    int head[maxn],dfn[maxn],low[maxn];
    int f[maxn][16],d[maxn];
    
    void add_edge(int u,int v){
        node[cnt].data=v;node[cnt].next=head[u];head[u]=cnt++;
        node[cnt].data=u;node[cnt].next=head[v];head[v]=cnt++;
    }
    
    void dfs(int x){
        dfn[x]=++Idex;
        for(int i=1;i<=15;i++)
            f[x][i]=f[f[x][i-1]][i-1];
        for(int point=head[x];point!=-1;point=then)
            if(now!=f[x][0])
                f[now][0]=x,d[now]=d[x]+1,dfs(now);
        low[x]=Idex;
    }
    
    int LCA(int x,int y){
        int tmp=d[x]-d[y];
        for(int i=15;i>=0;i--)
            if(tmp&(1<<i)) x=f[x][i];
        if(x==y) return x;
        for(int i=15;i>=0;i--)
            if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    
    int get_fa(int x,int k){
        for(int i=0;i<=15;i++)
            if((1<<i)&k) x=f[x][i];
        return x;
    }
    
    void add2(int x,int d){
        for(int i=x;i<=n;i+=i&-i) b[i]+=d;
    }
    
    void add(int l,int r,int d){
        add2(l,d),add2(r+1,-d);    
    }
    
    int ask(int x){
        int sum=0;
        for(int i=x;i;i-=i&-i) sum+=b[i];
        return sum;
    }
    
    void div(int H,int T,int l,int r){
        if(H>T) return ;
        if(l==r){
            for(int i=H;i<=T;i++)
                if(q[i].tp==3) ans[q[i].y]=l;
            return ;
        }
        int mid=(l+r)>>1;
        for(int i=H;i<=T;i++){
            if(q[i].tp==1 && q[i].k<=mid) add(q[i].x,q[i].y,1);
            else if(q[i].tp==2 && q[i].k<=mid) add(q[i].x,q[i].y,-1);
            else if(q[i].tp==3)
                tmp[i]=ask(q[i].x);
        }
        for(int i=H;i<=T;i++){
            if(q[i].tp==1 && q[i].k<=mid) add(q[i].x,q[i].y,-1);
            else if(q[i].tp==2 && q[i].k<=mid) add(q[i].x,q[i].y,1);
        }
        int l1=0,l2=0;
        for(int i=H;i<=T;i++){
            if(q[i].tp==3){
                if(q[i].cur+tmp[i]>=q[i].k) q1[++l1]=q[i];
                else q[i].cur+=tmp[i],q2[++l2]=q[i];
            }
            else{
                if(q[i].k<=mid) q1[++l1]=q[i];
                else q2[++l2]=q[i];
            }
        }
        for(int i=1;i<=l1;i++) q[H+i-1]=q1[i];
        for(int i=1;i<=l2;i++) q[H+l1+i-1]=q2[i];
        div(H,H+l1-1,l,mid);
        div(H+l1,T,mid+1,r);
    }
    
    bool cmp(const Query &A,const Query &B){
        if(A.rk!=B.rk) return A.rk<B.rk;
        return A.tp<B.tp;
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("fruit.in","r",stdin);
        freopen("fruit.out","w",stdout);
    #endif
    
        int u,v,v1,w;
    
        n=in();P=in();m=in();
        for(int i=1;i<=n;i++) head[i]=-1;
        for(int i=1;i<n;i++)
            u=in(),v=in(),add_edge(u,v);
        dfs(1);
        for(int i=1;i<=P;i++){
            u=in(),v=in(),w=in();
            if(d[u]>d[v]) swap(u,v);
            if(LCA(v,u)==u){
                v1=get_fa(v,d[v]-d[u]-1);
                q[++tot].tp=1,q[tot].rk=1,q[tot].x=dfn[v],q[tot].y=low[v],q[tot].k=w;
                q[++tot].tp=2,q[tot].rk=dfn[v1],q[tot].x=dfn[v],q[tot].y=low[v],q[tot].k=w;
                if(low[v1]+1<=n){
                    q[++tot].tp=1,q[tot].rk=dfn[v],q[tot].x=low[v1]+1,q[tot].y=n,q[tot].k=w;
                    q[++tot].tp=2,q[tot].rk=low[v]+1,q[tot].x=low[v1]+1,q[tot].y=n,q[tot].k=w;
                }
            }
            else{
                if(dfn[u]<dfn[v]) swap(u,v);
                q[++tot].tp=1,q[tot].rk=dfn[v],q[tot].x=dfn[u],q[tot].y=low[u],q[tot].k=w;
                q[++tot].tp=2,q[tot].rk=low[v]+1,q[tot].x=dfn[u],q[tot].y=low[u],q[tot].k=w;
            }
        }
        for(int i=1;i<=m;i++){
            u=in(),v=in();
            if(dfn[u]<dfn[v]) swap(u,v);
            q[++tot].rk=dfn[v],q[tot].x=dfn[u];
            q[tot].tp=3,q[tot].y=i,q[tot].k=in();
        }
        sort(q+1,q+tot+1,cmp);
        div(1,tot,0,INF);
        for(int i=1;i<=m;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    nginx 转发配置
    Rancher中httpd证书的管理和使用
    JDK-docker
    软路由
    rancher相关
    rancher部署
    电商 好文 知识积累
    SpringBlade 接口文档 请求token接口报错
    SpringBlade 接口文档 无法访问
    电商 好文
  • 原文地址:https://www.cnblogs.com/Robert-Yuan/p/5240209.html
Copyright © 2020-2023  润新知