• 【bzoj2809】dispatching


    这题的最优解法是可并堆,从上往下合并及删点,标准的O(nlogn)解法。

    为了练习主席树,特用主席树写一发,可以按dfs序建立主席树,对每个子树进行查询。

    总时间5232毫秒,要垫底了...

    看来需要去借鉴一下别人的主席树模板了。

    /**************************************************************
        Problem: 2809
        User: chad
        Language: C++
        Result: Accepted
        Time:5232 ms
        Memory:98144 kb
    ****************************************************************/
     
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    #include<algorithm>
    #include<iomanip>
    #include<map>
    #include<queue>
    using namespace std;
    #define mem1(i,j) memset(i,j,sizeof(i))
    #define mem2(i,j) memcpy(i,j,sizeof(i))
    #define LL long long
    #define up(i,j,n) for(LL i=(j);i<=(n);i++)
    #define FILE "dealing"
    #define poi vec
    #define eps 1e-10
    #define mid (l+r>>1)
    #define db double
    const LL maxn=102000,inf=1000000000,mod=1000000007;
    LL read(){
        LL x=0,f=1,ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0',ch=getchar();}
        return f*x;
    }
    bool cmax(LL& a,LL b){return a<b?a=b,true:false;}
    bool cmin(LL& a,LL b){return a>b?a=b,true:false;}
    LL n,m;
    struct node{LL y,next;}e[maxn<<1];
    int len=0,linkk[maxn<<1],L[maxn],id[maxn],fa[maxn],v[maxn],q[maxn],pre[maxn],t[maxn],low[maxn],dfs_clock=0;
    void insert(LL x,LL y){e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;}
    LL rt=0;
    struct Node{LL x,y,z;}a[maxn];
    bool cmp(const Node a,const Node b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
    bool cmp2(const Node a,const Node b){return pre[a.y]<pre[b.y];}
    bool cmp3(const Node a,const Node b){return a.y<b.y;}
    void dfs(LL x){
        pre[x]=++dfs_clock;
        for(LL i=linkk[x];i;i=e[i].next){
            if(e[i].y==fa[x])continue;
            dfs(e[i].y);
        }
        low[x]=dfs_clock;
    }
    LL r[2200000],sum[2200000],c[2200000][2],val[2200000],cnt=0;
    void updata(LL x){                    //val的和
        sum[x]=sum[c[x][0]]+sum[c[x][1]];
        val[x]=val[c[x][0]]+val[c[x][1]];
    }
    void set(LL& o,LL rt,LL key,LL l,LL r){
        if(!o)o=++cnt;
        if(l==r){val[o]=a[key].x;sum[o]=1;return;}
        if(key<=mid)c[o][1]=c[rt][1],set(c[o][0],c[rt][0],key,l,mid);
        else c[o][0]=c[rt][0],set(c[o][1],c[rt][1],key,mid+1,r);
        updata(o);
    }
     
    void init(){up(i,1,n)set(r[i],r[i-1],t[i],1,n);}
     
    LL shu=0,y=m,d;
    void walk(LL o1,LL o2,LL l,LL r){
        if(val[c[o2][0]]-val[c[o1][0]]<=y)y-=(val[c[o2][0]]-val[c[o1][0]]),shu+=sum[c[o2][0]]-sum[c[o1][0]],d=1;
        else d=0;
        if(l==r)return;
        if(!d)walk(c[o1][0],c[o2][0],l,mid);
        else walk(c[o1][1],c[o2][1],mid+1,r);
    }
    LL query(LL L,LL R){
        shu=0;y=m;walk(r[L],r[R],1,n);
        return shu;
    }
    int main(){
        //freopen(FILE".in","r",stdin);
        //freopen(FILE".out","w",stdout);
        n=read(),m=read();
        up(i,1,n){        //薪水         领导力
            fa[i]=read(),v[i]=read(),L[i]=read();
            a[i].x=v[i],a[i].y=i;
            if(!fa[i])rt=i;
            else insert(i,fa[i]),insert(fa[i],i);
        }
        dfs(rt);
        sort(a+1,a+n+1,cmp);
        up(i,1,n)t[pre[a[i].y]]=i;
        up(i,1,n)id[pre[i]]=i;//第i个位置的原节点为id[i]
        init();
        LL ans=0;
        up(i,1,n)ans=max(ans,(LL)query(pre[i]-1,low[i])*L[i]);
        cout<<ans<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    如何在Ubuntu 20.04 LTS Focal Fossa上安装Webmin
    如何在Linux服务器上创建一个具有管理权限的新用户?
    如何在Ubuntu 20.04 LTS上安装Apache Subversion
    error more than one devices and emulator
    深度学习+CRF解决NER问题
    word2vec训练&IC分词(待)
    tensorflow基础
    (转)pycharm快捷键
    Python包的相对导入时出现问题解决
    python工具使用笔记
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6428655.html
Copyright © 2020-2023  润新知