zoukankan      html  css  js  c++  java
  • BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]

    传送门

    题意:查询树上根节点值*子树中权值和$le m$的最大数量 最大值是多少


    求$DFS$序,然后变成区间中和$le m$最多有几个元素,建主席树,然后权值线段树上二分就行了

    $WA$:又把边表开小了.....

    好吧我$zz$了有根树加无向边干什么....

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define lc(x) t[x].l
    #define rc(x) t[x].r
    typedef long long ll;
    const int N=1e5+5;
    int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    int n,m,mp[N];
    struct Ninjia{
        int w,li,id;
        bool operator <(const Ninjia &r)const{return w<r.w;}
    }a[N];
    inline bool cmpId(Ninjia a,Ninjia b){return a.id<b.id;}
    struct Edge{
        int v,ne;
    }e[N<<1];
    int h[N],cnt;
    inline void ins(int u,int v){
        cnt++;
        e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
        cnt++;
        e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
    }
    int L[N],R[N],dfc,pos[N];
    void dfs(int u,int fa){
        L[u]=++dfc; pos[dfc]=u;
        for(int i=h[u];i;i=e[i].ne)
            if(e[i].v!=fa) dfs(e[i].v,u);
        R[u]=dfc;
    }
    
    struct Node{
        int l,r,size;
        ll sum;
    }t[N*30];
    int sz,root[N];
    void fIns(int &x,int l,int r,int p){
        t[++sz]=t[x];x=sz;
        t[x].size++;
        t[x].sum+=(ll)mp[p];
        if(l==r) return;
        int mid=(l+r)>>1;
        if(p<=mid) fIns(lc(x),l,mid,p);
        else fIns(rc(x),mid+1,r,p);
    }
    int fQue(int x,int y,int l,int r,ll m){
        //printf("fQue %d %d %d %d  %d %d %lld %lld
    ",x,y,l,r,t[x].size,t[y].size,t[x].sum,t[y].sum);
        if(l==r){
            ll lsum=t[y].sum-t[x].sum;
            return lsum<=m ? t[y].size-t[x].size : 0;
        }else{
            int mid=(l+r)>>1;
            ll lsum=t[lc(y)].sum-t[lc(x)].sum;//printf("lsum %lld %lld
    ",lsum,m);
            if(m<=lsum) return fQue(lc(x),lc(y),l,mid,m);
            else return t[lc(y)].size-t[lc(x)].size+fQue(rc(x),rc(y),mid+1,r,m-lsum);
        }
    }
    int rt=0,u;
    int main(){
        freopen("in","r",stdin);
        n=read();m=read();
        for(int i=1;i<=n;i++){
            u=read();if(u==0) rt=i;
            ins(u,i),a[i].w=read(),a[i].li=read(),a[i].id=i;
        }
        sort(a+1,a+1+n);
        for(int i=1;i<=n;i++) mp[i]=a[i].w,a[i].w=i;
        sort(a+1,a+1+n,cmpId);
        //for(int i=1;i<=n;i++) printf("a %d %d %d
    ",a[i].id,a[i].w,mp[a[i].w]);
        dfs(rt,0);
        //for(int i=1;i<=n;i++) printf("LR %d %d %d
    ",i,L[i],R[i]);
        //for(int i=1;i<=n;i++) printf("%d ",pos[i]);puts("");
        for(int i=1;i<=n;i++) root[i]=root[i-1],fIns(root[i],1,n,a[pos[i]].w);
        ll ans=0;
        for(int i=1;i<=n;i++) ans=max(ans,(ll)a[i].li*fQue(root[L[i]-1],root[R[i]],1,n,m));
        printf("%lld",ans);
    }
  • 相关阅读:
    redis要注意的一些知识
    redis数据类型及常用命令使用
    基于zookeeper的分布式锁
    基于redis的分布式锁
    基于数据库的分布式锁
    数据库的4中隔离级别
    远程调用历史及代码编写demo
    数据库的ACID跟事务隔离级别
    JAVA8 十大新特性详解
    java8 :: 用法 (JDK8 双冒号用法)
  • 原文地址:https://www.cnblogs.com/candy99/p/6491960.html
Copyright © 2011-2022 走看看