• L3-2 森森快递 (30 分)(贪心+线段树/分块)


    题目链接:https://pintia.cn/problem-sets/1108203702759940096/problems/1108204121661857798

    题目大意:

    森森开了一家快递公司,叫森森快递。因为公司刚刚开张,所以业务路线很简单,可以认为是一条直线上的N个城市,这些城市从左到右依次从0到(编号。由于道路限制,第i号城市(,)与第(号城市中间往返的运输货物重量在同一时刻不能超过Ci​​公斤。

    公司开张后很快接到了Q张订单,其中j张订单描述了某些指定的货物要从Sj​​号城市运输到Tj​​号城市。这里我们简单地假设所有货物都有无限货源,森森会不定时地挑选其中一部分货物进行运输。安全起见,这些货物不会在中途卸货。

    为了让公司整体效益更佳,森森想知道如何安排订单的运输,能使得运输的货物重量最大且符合道路的限制?要注意的是,发货时间有可能是任何时刻,所以我们安排订单的时候,必须保证共用同一条道路的所有货车的总重量不超载。例如我们安排1号城市到4号城市以及2号城市到4号城市两张订单的运输,则这两张订单的运输同时受2-3以及3-4两条道路的限制,因为两张订单的货物可能会同时在这些道路上运输。

    具体思路:首先对区间的右端点进行排序,先处理短的区间,再去处理长的区间,这样就能保证是最大了。其实就是区间查询和区间修改。

    作死用分块打的区间查询和区间修改,有一个两分的样例就是A不了。。以后这种区间修改还是用线段树吧,,

    分块代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 # define ll long long
      4 const ll inf =0x3f3f3f3f3f3f3f3f;
      5 const int maxn= 3e6+100;
      6 ll a[maxn];
      7 struct node
      8 {
      9     ll st;
     10     ll ed;
     11     bool friend operator < (node t1,node t2)
     12     {
     13         return t1.ed<t2.ed;
     14     }
     15 } q[maxn];
     16 ll vis[maxn];
     17 ll belong[maxn];
     18 ll l[maxn],r[maxn];
     19 ll  add[maxn];
     20 ll sum[maxn];
     21 ll  n,m;
     22 void build()
     23 {
     24     ll block=(ll)sqrt(n-1ll);
     25     for(ll i=1; i<n; i++)
     26         belong[i]=i/block+1ll;
     27     ll tot=(n-1)/block;
     28     if((n-1)%block)
     29         tot++;
     30     for(ll i=1; i<=tot; i++)
     31     {
     32         l[i]=(i-1)*block+1ll;
     33         r[i]=(i)*block;
     34     }
     35     r[tot]=n-1;
     36     for(ll i=1; i<=tot; i++)
     37     {
     38         sum[i]=inf;
     39         for(ll  j=l[i]; j<=r[i]; j++)
     40         {
     41             sum[i]=min(vis[j],sum[i]);
     42         }
     43     }
     44 }
     45 ll ask(ll st,ll ed)
     46 {
     47     ll ans=inf;
     48     if(belong[st]==belong[ed])
     49     {
     50         for(ll i=st; i<=ed; i++)
     51         {
     52             ans=min(ans,vis[i]+add[belong[st]]);
     53         }
     54         return ans;
     55     }
     56     for(ll i=st; i<=r[belong[st]]; i++)
     57         ans=min(ans,vis[i]+add[belong[st]]);
     58     for(ll i=l[belong[ed]]; i<=ed; i++)
     59         ans=min(ans,vis[i]+add[belong[ed]]);
     60     for(ll i=belong[st]+1; i<belong[ed]; i++)
     61         ans=min(ans,sum[i]+add[i]);
     62     return ans;
     63 }
     64 void  up(ll st,ll ed,ll val)
     65 {
     66     if(belong[st]==belong[ed])
     67     {
     68         for(ll i=st; i<=ed; i++)
     69         {
     70             vis[i]+=val;
     71             sum[belong[st]]=min(sum[belong[st]],vis[i]);
     72         }
     73         return ;
     74     }
     75     for(ll i=st; i<=r[belong[st]]; i++)
     76     {
     77         vis[i]+=val;
     78         sum[belong[st]]=min(sum[belong[st]],vis[i]);
     79     }
     80     for(ll i=l[belong[ed]]; i<=ed; i++)
     81     {
     82         vis[i]+=val;
     83         sum[belong[ed]]=min(sum[belong[ed]],vis[i]);
     84     }
     85     for(ll i=belong[st]+1; i<belong[ed]; i++)
     86     {
     87         add[i]+=val;
     88     }
     89 }
     90 signed  main()
     91 {
     92     // cout<<inf<<endl;
     93     scanf("%lld %lld",&n,&m);
     94     for(ll i=1; i<n; i++)
     95         scanf("%lld",&vis[i]);
     96     sort(q+1,q+m+1);
     97     build();
     98     ll st,ed;
     99     for(ll i=1; i<=m; i++)
    100     {
    101         scanf("%lld %lld",&q[i].st,&q[i].ed);
    102         q[i].st++;
    103         q[i].ed++;
    104         if (q[i].st > q[i].ed)
    105             swap(q[i].st, q[i].ed);
    106     }
    107     sort(q+1,q+m+1);
    108     ll sum=0;
    109     for(ll i=1; i<=m; i++)
    110     {
    111         ll minn;
    112         minn=ask(q[i].st,q[i].ed-1);
    113         sum+=minn;
    114         up(q[i].st,q[i].ed-1,-minn);
    115     }
    116     printf("%lld
    ",sum);
    117     return 0;
    118 }
    View Code

    线段树代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define ll long long
     4 # define lson l,m,rt<<1
     5 # define rson m,r,rt<<1|1
     6 const ll inf =0x3f3f3f3f3f3f3f;
     7 const int maxn= 3e6+100;
     8 struct node
     9 {
    10     ll st;
    11     ll ed;
    12     bool friend operator < (node t1,node t2)
    13     {
    14         return t1.ed<t2.ed;
    15     }
    16 } q[maxn];
    17 ll tree[maxn<<2],lazy[maxn<<2];
    18 void up(ll rt)
    19 {
    20     tree[rt]=min(tree[rt<<1],tree[rt<<1|1]);
    21 }
    22 void down(int rt)
    23 {
    24     tree[rt<<1]+=lazy[rt];
    25     tree[rt<<1|1]+=lazy[rt];
    26     lazy[rt<<1]+=lazy[rt];
    27     lazy[rt<<1|1]+=lazy[rt];
    28     lazy[rt]=0;
    29 }
    30 void build(ll l,ll r,ll rt)
    31 {
    32     if(l+1==r)
    33     {
    34         scanf("%lld",&tree[rt]);
    35         return ;
    36     }
    37     ll m=(l+r)>>1;
    38     build(lson);
    39     build(rson);
    40     up(rt);
    41 }
    42 ll ask(ll L,ll R,ll l, ll r,ll rt)
    43 {
    44     if(R<=l||L>=r)
    45         return inf ;
    46     if(L<=l&&R>=r)
    47     {
    48         return tree[rt];
    49     }
    50     ll m=(l+r)>>1ll;
    51     down(rt);
    52     return min(ask(L,R,lson),ask(L,R,rson));
    53 }
    54 void  update(ll L,ll R,ll l,ll r,ll rt,ll val)
    55 {
    56     if(R<=l||L>=r)
    57         return ;
    58     if(L<=l&&R>=r)
    59     {
    60         tree[rt]+=val;
    61         lazy[rt]+=val;
    62         return ;
    63     }
    64     ll m=(l+r)>>1;
    65     down(rt);
    66     update(L,R,lson,val);
    67     update(L,R,rson,val);
    68     up(rt);
    69 }
    70 int  main()
    71 {
    72     ll n,m;
    73     // cout<<inf<<endl;
    74     scanf("%lld %lld",&n,&m);
    75     build(1,n,1);
    76     ll st,ed;
    77     for(ll i=1; i<=m; i++)
    78     {
    79         scanf("%lld %lld",&q[i].st,&q[i].ed);
    80         q[i].st++;
    81         q[i].ed++;
    82         if (q[i].st > q[i].ed)
    83             swap(q[i].st, q[i].ed);
    84     }
    85     sort(q+1,q+m+1);
    86     ll sum=0;
    87     for(ll i=1; i<=m; i++)
    88     {
    89         ll minn;
    90         minn=ask(q[i].st,q[i].ed,1,n,1);
    91         sum+=minn;
    92         update(q[i].st,q[i].ed,1,n,1,-minn);
    93     }
    94     printf("%lld
    ",sum);
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    C 工具库7:local_pool
    进程间传递文件描述符
    ucontext实现的用户级多线程框架
    ucontext实现的用户级多线程框架2(抢先式多线程)
    网络接收缓存的设计
    利用用户级线程提高多线程应用的性能
    死锁检测
    网络服务器发送封包设计
    C 工具库8:map
    ucontext实现的用户级多线程框架3(实现echo服务器)
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10573088.html
Copyright © 2020-2023  润新知