bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle【贪心+线段树】

按结束时间排序,然后开个线段树,按照排序后的牛群贪心的选

贪心的依据是选哪头牛都是选,不如给后面的多省一点空间

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=50005;
int m,n,c,ans;
struct xds
{
    int l,r,mn,lz;
}t[N<<1];
struct qwe
{
    int s,t,m;
}a[N];
bool cmp(const qwe &a,const qwe &b)
{
    return a.t<b.t;
}
int read()
{
    int r=0,f=1;
    char p=getchar();
    while(p>‘9‘||p<‘0‘)
    {
        if(p==‘-‘)
            f=-1;
        p=getchar();
    }
    while(p>=‘0‘&&p<=‘9‘)
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r*f;
}
void build(int ro,int l,int r)
{
    t[ro].l=l,t[ro].r=r,t[ro].mn=c;
    if(l==r)
        return;
    int mid=(l+r)>>1;
    build(ro<<1,l,mid);
    build(ro<<1|1,mid+1,r);
}
void ud(int ro)
{
    t[ro<<1].lz+=t[ro].lz;
    t[ro<<1].mn+=t[ro].lz;
    t[ro<<1|1].lz+=t[ro].lz;
    t[ro<<1|1].mn+=t[ro].lz;
    t[ro].lz=0;
}
void update(int ro,int l,int r,int w)
{
    if(t[ro].l==l&&t[ro].r==r)
    {
        t[ro].lz+=w;
        t[ro].mn+=w;
        return;
    }
    ud(ro);
    int mid=(t[ro].l+t[ro].r)>>1;
    if(r<=mid)
        update(ro<<1,l,r,w);
    else if(l>mid)
        update(ro<<1|1,l,r,w);
    else
    {
        update(ro<<1,l,mid,w);
        update(ro<<1|1,mid+1,r,w);
    }
    t[ro].mn=min(t[ro<<1].mn,t[ro<<1|1].mn);
}
int ques(int ro,int l,int r)
{
    if(t[ro].l==l&&t[ro].r==r)
        return t[ro].mn;
    ud(ro);
    int mid=(t[ro].l+t[ro].r)>>1;
    if(r<=mid)
        return ques(ro<<1,l,r);
    else if(l>mid)
        return ques(ro<<1|1,l,r);
    else
        return min(ques(ro<<1,l,mid),ques(ro<<1|1,mid+1,r));
}
int main()
{
    m=read(),n=read(),c=read();
    for(int i=1;i<=m;i++)
        a[i].s=read(),a[i].t=read()-1,a[i].m=read();
    sort(a+1,a+1+m,cmp);
    // for(int i=1;i<=m;i++)
        // cerr<<a[i].s<<" "<<a[i].t<<" "<<a[i].m<<endl;
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        int nw=min(ques(1,a[i].s,a[i].t),a[i].m);
        if(nw)
        {
            update(1,a[i].s,a[i].t,-nw);
            ans+=nw;
        }
    }
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/lokiii/p/9246083.html

时间: 2024-08-26 04:46:21

bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle【贪心+线段树】的相关文章

bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle——小根堆+大根堆+贪心

Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1<=Mi<=N)只. 他们希望从Si到Ei去.公交车只能座C(1<=C<=100)只奶牛.而且不走重复路线,请计算这辆车最多能满足多少奶牛听要求.注意:对于每一群奶牛,可以部分满足,也可以全部满足,也可以全部不满足. Input 第1行: 三个整数: K,N,C. 由空格隔开. 第2..

[bzoj1577][Usaco2009 Feb]庙会捷运Fair Shuttle_贪心_线段树

庙会捷运 Fair Shuttle bzoj-1577 Usaco-2009 Feb 题目大意:有一辆公交车从1走到n.有m群奶牛从$S_i$到$E_i$,第i群奶牛有$W_i$只.车有一个容量c.问不走回头路的情况下最多使多少奶牛到达目的地.其中,每一群奶牛不一定都拉走. 注释:$1\le n\le 2\cdot 10^4$,$1\le m\le 5\cdot 10^4$,$1\le c\le 100$. 想法:开始觉得是个裸贪心,但是没法维护.其实是这样的: 我们将所有的奶牛群排序:右端点为

[Usaco2009 Feb]庙会捷运Fair Shuttle

Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1<=Mi<=N)只. 他们希望从Si到Ei去. 公交车只能座C(1<=C<=100)只奶牛.而且不走重复路线,请计算这辆车最多能满足多少奶牛听要求. 注意:对于每一群奶牛,可以部分满足,也可以全部满足,也可以全部不满足. Input 第1行: 三个整数: K,N,C. 由空格隔开. 第2

BZOJ1577: [Usaco2009 Feb]庙会捷运Fair Shuttle

n<=20000个车站,车能同时载C<=100个人,求能满足K<=50000群人的多少个.每群人给起点终点和人数,一群人不一定要都满足. 一开始想DP,想不出,很菜. 贪心即可.如果有右端点相同的几群人,那肯定优先满足左端点大的:如果有两群人发生冲突,而我们从左到右考虑区间的话,那肯定让左边的人先满足,因为他对后面的人影响小.所以先排个序然后模拟即可.模拟用线段树. 1 #include<stdio.h> 2 #include<string.h> 3 #inclu

【Luogu】P1607庙会班车Fair Shuttle(线段树+贪心)

我不会做贪心题啊--贪心题啊--题啊--啊-- 我真TM菜爆了啊-- 这题就像凌乱的yyy一样,把终点排序,终点相同的按起点排序.然后维护一个查询最大值的线段树.对于一个区间[l,r],如果这个区间已经有的最大值为s,那么这个区间最多还能装下c-s头奶牛. 当然奶牛数量没那么多的话我也是没有办法 最后说一句,奶牛到终点就下车了,可以给别的奶牛腾空间,不计入个数.所以奶牛在车上的区间为[l,r-1]. #include <cstdio> #include <iostream> #in

BZOJ 3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛( dp )

水题...忘了取模就没1A了.... --------------------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; const int MOD = 5000011; const int maxn = 100009; int dp[maxn], n, k; int main() { cin >> n >> k;

Bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级 dijkstra,堆,分层图

1579: [Usaco2009 Feb]Revamping Trails 道路升级 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1573  Solved: 428[Submit][Status][Discuss] Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i (1 <= P1_i <= N;

BZOJ 1579: [Usaco2009 Feb]Revamping Trails 道路升级( 最短路 )

最短路...多加一维表示更新了多少条路 ---------------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<queue> #include<cstring> #include<iostream> #define rep( i , n ) for( int i

bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级 优先队列+dij

1579: [Usaco2009 Feb]Revamping Trails 道路升级 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1768  Solved: 481[Submit][Status][Discuss] Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i (1 <= P1_i <= N;