轻轨【线段树】【贪心】

题目大意:

N个站点的轻轨站,有一个容量为C的列车起点在1号站点,终点在N号站点,有K组牛群,每组数量为M[i],行程起点和终点分别为S[i]E[i]。请你计算最多有多少头牛可以搭乘轻轨。


思路:

线段树+贪心

其实这道题直接用贪心就能过,编程复杂度也简单,但是就是比较难理解。
这道题如果我们将每群牛的起点和终点看成起始时间和终止时间,C看做会场场数,那么这道题就很像 活动安排 了。
每次查询起点和终点的之间的最大值,将牛尽量放进车上,并标记这个区间新添加了这么多牛,中间所有添加的牛的数量即为答案。

这里写图片描述


代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

int n,m,k,sum,ans,sum2;

struct node1
{
    int l,r,max,lazy;
}tree[300001];

struct node2
{
    int l,r,num;
}a[300001];

void make(int x)
{
    if (tree[x].r==tree[x].l) return;
    int mid=(tree[x].l+tree[x].r)/2;
    tree[x*2].l=tree[x].l;
    tree[x*2].r=mid;
    tree[x*2+1].l=mid+1;
    tree[x*2+1].r=tree[x].r;
    make(x*2);
    make(x*2+1);
}

bool cmp(node2 x,node2 y)
{
    return x.r<y.r||(x.r==y.r&&x.l<y.l);
}

void pushdown(int x)
{
    if (tree[x].lazy)
    {
        tree[x*2].lazy+=tree[x].lazy;
        tree[x*2+1].lazy+=tree[x].lazy;
        tree[x*2].max+=tree[x].lazy;
        tree[x*2+1].max+=tree[x].lazy;
        tree[x].lazy=0;
    }
}

int find(int x,int l,int r)
{
    if (tree[x].l>r||tree[x].r<l) return 0;
    if (tree[x].l>=l&&tree[x].l<=r) return tree[x].max;
    pushdown(x);
    int lmax=find(x*2,l,r);
    int rmax=find(x*2+1,l,r);
    tree[x].max=max(tree[x*2].max,tree[x*2+1].max);
    int maxn=max(lmax,rmax);
    return maxn;
}

void add(int x,int l,int r,int k)
{
    if (tree[x].l>r||tree[x].r<l) return;
    if (tree[x].l>=l&&tree[x].r<=r) 
    {
        tree[x].max+=k;
        tree[x].lazy+=k;
        return;
    }
    pushdown(x);
    add(x*2,l,r,k);
    add(x*2+1,l,r,k);
    tree[x].max=max(tree[x*2].max,tree[x*2+1].max);
}

int main()
{
    scanf("%d%d%d",&m,&n,&k);
    tree[1].l=1;
    tree[1].r=n;
    make(1);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].num);
    }
    sort(a+1,a+1+m,cmp);
    for (int i=1;i<=m;i++)
    {
        sum=find(1,a[i].l,a[i].r);
        if (k<sum) continue;
        sum2=min(a[i].num,k-sum);
        ans+=sum2;
        add(1,a[i].l,a[i].r-1,sum2);
    }
    return printf("%d\n",ans)&0;
}
posted @ 2018-07-12 07:56  全OI最菜  阅读(113)  评论(0编辑  收藏  举报