zoukankan      html  css  js  c++  java
  • 线段树【p1607】[USACO09FEB]庙会班车Fair Shuttle

    Description

    逛逛集市,兑兑奖品,看看节目对农夫约翰来说不算什么,可是他的奶牛们非常缺乏锻炼——如果要逛完一整天的集市,他们一定会筋疲力尽的。所以为了让奶牛们也能愉快地逛集市,约翰准备让奶牛们在集市上以车代步。但是,约翰木有钱,他租来的班车只能在集市上沿直线跑一次,而且只能停靠N(1 ≤N≤20000)个地点(所有地点都以1到N之间的一个数字来表示)。现在奶牛们分成K(1≤K≤50000)个小组,第i 组有Mi(1 ≤Mi≤N)头奶牛,他们希望从Si跑到Ti(1 ≤Si<Ti≤N)。

    由于班车容量有限,可能载不下所有想乘车的奶牛们,此时也允许小里的一部分奶牛分开乘坐班车。约翰经过调查得知班车的容量是C(1≤C≤100),请你帮助约翰计划一个尽可能满足更多奶牛愿望的方案。

    Input

    第一行:包括三个整数:K,N和C,彼此用空格隔开。

    第二行到K+1行:在第i+1行,将会告诉你第i组奶牛的信息:Si,Ei和Mi,彼

    Output

    第一行:可以坐班车的奶牛的最大头数。

    的确,这是一道线段树好题.

    不过貌似正解是贪心.

    算了,写了都写了,就来BB两句.

    显然,这会是一个区间问题,而这个区间问题需要考虑的是当前这段区间内车的剩余容量.

    明显的是,对于一段区间内车的剩余容量我们需要知道其最小的容量。才能知道能否继续有奶牛上车。

    修改的时候的话,需要修改([s_i,t_i-1])的区间最大值.

    这就考虑成当前批次的奶牛会在(t_i)下车,又会有新的一批奶牛在(t_i)上车。

    问题就是线段树维护动态区间最大值。(是叫这个吧 emm

    代码

    #include<cstdio>
    #include<cctype>
    #include<iostream>
    #include<algorithm>
    #define ls o<<1
    #define rs o<<1|1
    #define R register
    using namespace std;
    inline void in(int &x)
    {
    	int f=1;x=0;char s=getchar();
    	while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    	while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    	x*=f;
    }
    int n,m,c,tr[20008*8],tg[20008*8],ans;
    struct cod{
    	int s,t,m;
    	bool operator <(const cod&a)
    	const 
    	{
    		return t<a.t;
    	}
    }cow[200008];
    inline void up(int o){tr[o]=max(tr[ls],tr[rs]);}
    void build(int o,int l,int r)
    {
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	build(ls,l,mid);
    	build(rs,mid+1,r);
    }
    inline void down(int o,int l,int r)
    {
    	if(tg[o])
    	{
    		tr[ls]+=tg[o],tr[rs]+=tg[o];
    		tg[ls]+=tg[o],tg[rs]+=tg[o];
    		tg[o]=0;
    	}
    }
    void change(int o,int l,int r,int x,int y,int z)
    {
    	if(x<=l and y>=r)
    	{
    		tr[o]+=z;tg[o]+=z;
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(x<=mid)change(ls,l,mid,x,y,z);
    	if(y>mid) change(rs,mid+1,r,x,y,z);
    	up(o);
    }
    int query(int o,int l,int r,int x,int y)
    {
    	if(x<=l and y>=r) return tr[o];
    	down(o,l,r);
    	int mid=(l+r)>>1,res=-214748364;
    	if(x<=mid)res=max(res,query(ls,l,mid,x,y));
    	if(y>mid)res=max(res,query(rs,mid+1,r,x,y));
    	return res;
    }
    int main()
    {
    	in(m),in(n),in(c);
    	for(R int i=1;i<=m;i++)
    		in(cow[i].s),in(cow[i].t),in(cow[i].m);
    	sort(cow+1,cow+m+1);
    	build(1,1,n);
    	for(R int i=1;i<=m;i++)
    	{
    		int now=query(1,1,n,cow[i].s,cow[i].t),res=0;
    		if(now>=c)continue;
    		if(now+cow[i].m<=c)res=cow[i].m;
    		else res=c-now;
    		ans+=res;
    		change(1,1,n,cow[i].s,cow[i].t-1,res);
    	}
    	printf("%d",ans);
    }
    
  • 相关阅读:
    C# 委托事件
    用netstat查看网络状态详解
    详解TCP建立连接全过程
    Amazon SNS移动推送更新——新增百度云推送和Windows平台支持
    UE-9260使用说明2
    简单理解javascript中的原型对象,实现对之间共享属性和行为
    RxJava
    链式存储(头插法、尾插法)
    Codeforces 569 B. Inventory
    CentOS 6.4安装Puppet
  • 原文地址:https://www.cnblogs.com/-guz/p/9776034.html
Copyright © 2011-2022 走看看