• 区间前k小的和(权值线段树+离散化)--2019牛客多校第7场C--砍树


    题目链接:https://ac.nowcoder.com/acm/contest/887/C?&headNav=acm

    题意:

    给你 n 种树,有 高度,花费和数量 ,现在问你最少需要花多少钱使得最高的树的数量占总数的一半以上

    思路:

    其实就是先把高度离散化一下(不离散化也没事),再按树的高度从低到高排一下序,枚举最高的树。

    比如当前枚举的是 H,那花费就是(>H)的树的所有花费+(<H)的最多剩下num-1棵树,用权值线段树记录花费花费的个数,每次查询前k小个就可以了。

      1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
      2 #include <cstdio>//sprintf islower isupper
      3 #include <cstdlib>//malloc  exit strcat itoa system("cls")
      4 #include <iostream>//pair
      5 #include <fstream>
      6 #include <bitset>
      7 //#include <map>
      8 //#include<unordered_map>   https://ac.nowcoder.com/acm/contest/887/C?&headNav=acm
      9 #include <vector>
     10 #include <stack>
     11 #include <set>
     12 #include <string.h>//strstr substr
     13 #include <string>
     14 #include <time.h>//srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
     15 #include <cmath>
     16 #include <deque>
     17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
     18 #include <vector>//emplace_back
     19 //#include <math.h>
     20 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
     21 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
     22 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
     23 #define fo(a,b,c) for(register int a=b;a<=c;++a)
     24 #define fr(a,b,c) for(register int a=b;a>=c;--a)
     25 #define mem(a,b) memset(a,b,sizeof(a))
     26 #define pr printf
     27 #define sc scanf
     28 #define ls rt<<1
     29 #define rs rt<<1|1
     30 void swapp(int &a,int &b);
     31 double fabss(double a);
     32 int maxx(int a,int b);
     33 int minn(int a,int b);
     34 int Del_bit_1(int n);
     35 int lowbit(int n);
     36 int abss(int a);
     37 const long long INF=(1LL<<60);
     38 const double E=2.718281828;
     39 const double PI=acos(-1.0);
     40 const int inf=(1<<29);
     41 const double ESP=1e-9;
     42 const int mod=(int)1e9+7;
     43 const int N=(int)1e5+10;
     44 
     45 int n;
     46 struct node_
     47 {
     48     int h,num,cost;
     49     friend bool operator<(node_ a,node_ b)
     50     {
     51         return a.h>b.h;
     52     }
     53 }arr[N];
     54 int b[N];
     55 int LS(int n)
     56 {
     57     int m=0;
     58     for(int i=1; i<=n; ++i)
     59         b[++m]=arr[i].h;
     60     sort(b+1,b+1+m);
     61     m=unique(b+1,b+1+m)-b-1;
     62     for(int i=1; i<=n; ++i)
     63         arr[i].h=lower_bound(b+1,b+1+m,arr[i].h)-b;
     64     return m;
     65 }
     66 //================================================离散化;
     67 struct node
     68 {
     69     long long cnt;
     70     long long sum;
     71 }tr[N<<2];
     72 void Build(int l,int r,int rt)
     73 {
     74     tr[rt].sum=tr[rt].cnt=0;
     75     if(l==r)return;
     76     int mid=(l+r)>>1;
     77     Build(l,mid,rt<<1);
     78     Build(mid+1,r,rt<<1|1);
     79 }
     80 void update_dot(int cost,int cnt,int l,int r,int rt)
     81 {
     82     tr[rt].sum+=cost*cnt;
     83     tr[rt].cnt+=cnt;
     84     if(l==r)return;
     85 
     86     int mid=(l+r)>>1;
     87     if(cost<=mid)
     88         update_dot(cost,cnt,l,mid,rt<<1);
     89     else
     90         update_dot(cost,cnt,mid+1,r,rt<<1|1);
     91 }
     92 long long Query(long long sum,int l,int r,int rt)
     93 {
     94     if(sum==0)return 0;
     95     if(l==r)
     96     {
     97         return sum*l;
     98     }
     99     int mid=(l+r)>>1;
    100     long long ans=0;
    101 
    102     if(sum<=tr[ls].cnt)
    103         ans+=Query(sum,l,mid,ls);
    104     else
    105         ans+=Query(sum-tr[ls].cnt,mid+1,r,rs)+tr[ls].sum;
    106     return ans;
    107 }
    108 void check(int pos,int l,int r,int rt)
    109 {
    110     if(l==r)
    111     {
    112         pr("%lld %lld
    ",tr[rt].cnt,tr[rt].sum);
    113         return ;
    114     }
    115     int mid=(l+r)>>1;
    116 
    117     if(pos<=mid)
    118         check(pos,l,mid,rt<<1);
    119     else
    120         check(pos,mid+1,r,rt<<1|1);
    121 }
    122 void C(int tot)
    123 {
    124     fo(i,1,n)
    125         check(i,1,tot,1);
    126     pr("----------------------------------
    ");
    127 }
    128 long long dp[N];
    129 vector<vector<int> >v(N);
    130 
    131 int main()
    132 {
    133     while(~sc("%d",&n))
    134     {
    135         fo(i,1,n)sc("%d%d%d",&arr[i].h,&arr[i].cost,&arr[i].num);
    136         arr[n+1].num=arr[n+1].cost=arr[n+1].h=0;
    137         LS(n);
    138         sort(arr+1,arr+1+n);
    139         fo(i,1,n)
    140             dp[i]=dp[i-1]+arr[i].cost*arr[i].num,v[i].clear();
    141         long long ans=INF;
    142         int vcnt=0;
    143         long long cnt=0;
    144         long long CNT=0;
    145         int ncnt=0;
    146         for(int i=n;i>=1;--i)
    147         {
    148             if(arr[i].h!=arr[i+1].h)
    149                 v[++vcnt].push_back(i);
    150             else
    151                 v[vcnt].push_back(i);
    152         }
    153         Build(1,200,1);
    154         int sz=v[1].size();//vector用来存相同高度的树团体
    155         fo(i,0,sz-1)
    156             update_dot(arr[v[1][i]].cost,arr[v[1][i]].num,1,200,1),CNT+=arr[v[1][i]].num;
    157         ans=min(ans,dp[n-sz]);
    158         ncnt=sz;
    159         fo(i,2,vcnt)
    160         {
    161             int sz_=v[i].size();
    162             fo(j,0,sz_-1)
    163                 cnt+=arr[v[i][j]].num;
    164             ncnt+=sz_;
    165             long long k=max(0LL,CNT-(cnt-1));
    166             ans=min(ans,Query(k,1,200,1)+dp[n-ncnt]);
    167             fo(j,0,sz_-1)
    168                 update_dot(arr[v[i][j]].cost,arr[v[i][j]].num,1,200,1);
    169             CNT+=cnt;
    170             cnt=0;
    171         }
    172         pr("%lld
    ",ans);
    173     }
    174     return 0;
    175 }
    176 
    177 /**************************************************************************************/
    178 
    179 int maxx(int a,int b)
    180 {
    181     return a>b?a:b;
    182 }
    183 
    184 void swapp(int &a,int &b)
    185 {
    186     a^=b^=a^=b;
    187 }
    188 
    189 int lowbit(int n)
    190 {
    191     return n&(-n);
    192 }
    193 
    194 int Del_bit_1(int n)
    195 {
    196     return n&(n-1);
    197 }
    198 
    199 int abss(int a)
    200 {
    201     return a>0?a:-a;
    202 }
    203 
    204 double fabss(double a)
    205 {
    206     return a>0?a:-a;
    207 }
    208 
    209 int minn(int a,int b)
    210 {
    211     return a<b?a:b;
    212 }
  • 相关阅读:
    自动从vss下载代码并编译的脚本
    自动执行Sql脚本的批处理
    编译 SharpDevelop2.2源码 经过
    .net框架源代码批量下载器使用方法
    sql server 解决孤立用户问题
    元数据学习分享
    SQL注入攻击的原理及其防范措施(转)
    .Net Remoting和Web Service浅析(转)
    usercontrol 和 page 的继承
    如何提高页面现实速度
  • 原文地址:https://www.cnblogs.com/--HPY-7m/p/11328589.html
Copyright © 2020-2023  润新知