zoukankan      html  css  js  c++  java
  • P1552 [APIO2012]派遣(线段树合并)

    以m的总价在线段树中找能雇佣的最大人数,然后向上合并

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include"vector"
      5 #define cint const int
      6 #define newnode() ++idx
      7 #include"iostream"
      8 using namespace std;
      9 int lch[3000010],rch[3000010];
     10 long long sum[3000010];
     11 int cnt[3000010];
     12 int idx;
     13 int root[100010];
     14 struct node{
     15     int a,b;
     16     inline bool operator<(const node &v)const{return a<v.a;}
     17 };
     18 node t[100010];
     19 
     20 int n,m;
     21 int b[100010],c[100010];
     22 long long l[100010];
     23 
     24 int rk[100010];
     25 long long ans;
     26 
     27 void merge(int &u,cint &v,int l,int r){
     28     
     29     
     30     if((!u)||(!v)){
     31         sum[u+v]=sum[u]+sum[v];
     32         cnt[u+v]=cnt[u]+cnt[v];
     33         u=v+u;
     34     }
     35     else if (l==r)
     36     {
     37         sum[u]+=sum[v];
     38         cnt[u]+=cnt[v];
     39         return ;
     40     }
     41     else {
     42         int mid =l+r>>1;
     43          merge(lch[u],lch[v],l,mid);
     44         merge(rch[u],rch[v],mid+1,r);
     45         sum[u]=sum[lch[u]]+sum[rch[u]];
     46         cnt[u]=cnt[lch[u]]+cnt[rch[u]];
     47     }
     48 }
     49 void ins(cint &u,cint &left,cint &right,cint &pos,cint &w){
     50     sum[u]+=w;
     51     ++cnt[u];
     52     if (right==left)return ;
     53     
     54             if(pos<=((left+right)>>1)){
     55             if(!lch[u])lch[u]=newnode();
     56             ins(lch[u],left,(left+right)>>1,pos,w);
     57         }else{
     58             if(!rch[u])rch[u]=newnode();
     59             ins(rch[u],(left+right)/2+1,right,pos,w);
     60         }
     61     
     62     
     63 }
     64 
     65 vector<int > v;
     66 
     67 int vv[600000];
     68 int bisearch(cint &u,cint &left,cint &right,cint &limit){
     69     if(!u)return 0;
     70     if(right>left)
     71     {
     72         if(sum[lch[u]]<=limit)
     73             return cnt[lch[u]]+bisearch(rch[u],(left+right)/2+1,right,limit-sum[lch[u]]);
     74         else
     75             return bisearch(lch[u],left,(left+right)>>1,limit);
     76     }
     77     else
     78     {
     79         
     80         //if (right==n+1)return 0;
     81         return min(cnt[u],limit/(vv[right]));
     82         //if(sum[u]<=limit)return 1;
     83     //    return 0;
     84        
     85     }
     86     
     87     
     88 }
     89 
     90 
     91 
     92 int main(){
     93 /*     n=5; root[1]=++idx;
     94     ins(root[1],1,n,2,2) ;
     95    root[2]=++idx;
     96     ins(root[2],1,n,2,3);
     97     cout<<sum[root[2]];
     98     merge(root[2],root[1],1,n);
     99     cout<<sum[root[2]];
    100     
    101     */
    102     int i,j,k;
    103     scanf("%d%d",&n,&m);
    104     for(i=1;i<=n;++i){
    105         scanf("%d%d%lld",b+i,c+i,l+i);
    106         t[i]={c[i],i};
    107        vv[i]=c[i];
    108     }
    109     stable_sort(t+1,t+n+1);
    110     
    111     t[0].a=-1;int now = 0;
    112     
    113     
    114     
    115   //  sort(v.begin(),v.end());
    116    // v.erase(unique(v.begin(),v.end()),v.end());
    117     sort(vv+1,vv+1+n); int tote;
    118      tote=unique(vv+1,vv+1+n)-vv-1;;
    119     
    120     
    121     for(i=1;i<=n;++i)
    122     {
    123     
    124         k=t[i].b;
    125         rk[k]=lower_bound(vv+1,vv+1+tote,t[i].a)-vv;
    126         //cout<<rk[k]<<endl;
    127         root[k]=newnode();
    128         ins(root[k],1,n,rk[k],c[k]);
    129        // cout<<k<<" "<<sum[root[k]]<<" "<<cnt[root[k]]<<endl;
    130         
    131     }
    132   //  cout<<"***********"<<endl;
    133     for(i=n;i;--i)
    134     {
    135     //    cout<<i<<" "<<sum[root[i]]<<" "<<bisearch(root[i],1,n,m)<<endl;
    136         //    cout<<i<<endl;
    137         ans=max(ans,l[i]*bisearch(root[i],1,n,m));
    138       //  cout<<b[i]<<" "<<sum[root[b[i]]]<<endl;
    139         if(b[i])merge(root[b[i]],root[i],1,n);
    140        //  cout<<b[i]<<" "<<sum[root[b[i]]]<<endl;
    141         
    142     }
    143     printf("%lld
    ",ans);
    144 }
  • 相关阅读:
    对象序列化流使用
    字符输入流结合字符打印流实现复制文件
    python 安装一些 直接使用pip无法安装的包 的方法
    linux记不住
    SIP
    uniapp不同型号手机适配
    uniapp app头部渐变
    vue安卓苹果下载链接合并
    Typescript
    Nodejs
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10349495.html
Copyright © 2011-2022 走看看