P05527 [Usaco2009 Feb]庙会捷运加强版

庙会捷运Fair Shuttle

公交车一共经过 n 个站点,从站点 1 一直驶到站点 n。k群奶牛希望搭乘这辆公交车。第 ii 群牛一共有 m_i只。
他们希望从 s_i到 e_i去。 公交车只能坐 c 只奶牛。而且不走重复路线,请计算这辆车最多能满足多少奶牛的要求。
注意:对于每一群奶牛,可以部分满足,也可以全部满足,也可以全部不满足。

输入格式
第 11 行: 三个整数:k,n,c由空格隔开。

第 2∼k+1 行:第i+1 行,告诉你第 ii 组奶牛的信息:s_i,e_i,m_i。由空格隔开。

输出格式
一行:可以在庙会乘坐捷运的牛的最大头数

输入数据 1
8 15 3
1 5 2
13 14 1
5 8 3
8 14 2
14 15 1
9 12 1
12 15 2
4 6 1
输出数据 1
10

 

N<=5e4 。。。。。。。。站台

K<=1e5。。。。。。。。多少批人

C<=2e4。。。。。。。。车的容量

 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1050010;
struct node 
{
	int l,r,w;
} e[maxn];
map<int,int,greater<int> > mp;
int n,m,c,cap,head,ans;
int sum; 
map<int,int>::iterator del[1100000];
bool cmp(node a, node b) 
{
	if (a.l==b.l)
		return a.r<b.r;
	else
		return a.l<b.l;
}
int main() {
	scanf("%d%d%d", &m, &n, &c);
	for (int i=1; i<=m; i++) {
		scanf("%d%d%d", &e[i].l, &e[i].r, &e[i].w);
	}
	sort(e+1,e+1+m,cmp);
	mp.clear();
    cap=0;
	map<int,int>::iterator it,it2;
	//最好不要定义成auto类型 
	head=1;
	ans=0;
	for (int now=1; now<=n; now++) 
	{
		if (mp[now]>0)
		{
			ans+=mp[now];
			cap-=mp[now];
			it=mp.find(now);
			mp.erase(it);
		}
		while (e[head].l<now)
			   head++;
		while (e[head].l==now) 
		{
			int to=e[head].r,num=e[head].w;
			int t=min(c-cap,num);
			cap=cap+t;
			num=num-t;
			mp[to]=mp[to]+t;
			if (cap==c && num)
			{
				it=mp.begin();
				sum=0;
				while (it!=mp.end())
				{
					if ((it->first)>to)
					{
						if ((it->second)>num)
						{
							(it->second)-=num;
							    mp[to]+=num;
							  break;
						} 
						else
						{
							mp[to]+=(it->second);
							num-=(it->second);
							sum++;
							del[sum]=it;
							it++;
						
						}
					} 
					else
						    break;
				}
				for (int k=1;k<=sum;k++)
				     mp.erase(del[k]);
			}
			head++;
		}
	}
	printf("%d\n", ans);
	return 0;
}

  

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
const int M=1e5+1000;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int f[2*M],cnt,cost,k,n,c,ans;
struct pos
{
    int id,h,ed;
    bool operator <(const pos &x)const{return x.ed<ed;}
};
std::vector<pos>e[M];
std::priority_queue<pos>q1;
//q1这个堆以结束位置为关键字,从小到大
struct Q
{
    int id,h,ed;
    bool operator <(const Q &x)const{return x.ed>ed;}
};
std::priority_queue<Q>q2;
//q2这个堆以结束位置为关键字,从大到
int main()
{
    int v,x,y;
    k=read(); n=read(); c=read();
    //k个旅行团,N个站点,容量为C
    for(int i=1;i<=k;i++) //读入K个旅行团
         x=read(),y=read(),v=read(),e[x].push_back((pos){++cnt,v,y});
    //按开始站点分类,将编号,人数,终点站加入各个的vector
    for(int i=1;i<=n;i++) //枚举结束站点
    {
        while(!q1.empty())
        //先下飞机
        {
            pos x=q1.top();
            if(x.ed>i)
                break;
            if(x.ed==i) //堆顶元素代表的旅行团到站了
            {
              q1.pop();
              if(f[x.id])
                continue;
              f[x.id]=1;
              cost-=x.h;
              ans+=x.h;
            }
        }
        int mx=e[i].size();
        //再上飞机
        for(int j=0;j<mx;j++)
        //将以这个时间点发出发点的旅行团加入两个堆中
        {
            q1.push((pos){e[i][j].id,e[i][j].h,e[i][j].ed});
            q2.push((Q){e[i][j].id,e[i][j].h,e[i][j].ed});
            cost+=e[i][j].h;
        }
        while(cost>c)
        //飞机超载了的话,就要让一些人下飞机
        {
            Q x=q2.top();
            q2.pop();
            if(f[x.id])
                continue;
            f[x.id]=1;
            //lazy标记,代表这波要被T掉
            if(cost-c>=x.h)
            //如果超载人数大于堆顶元素的人
            //就让这波人全下飞机
               {
                   cost-=x.h;
                   continue;
               }
            //否则只能让一部分人下飞机
            //将这波人另设成一个旅行团,加入堆中
            int now=cost-c;
            cnt++;
            q1.push((pos){cnt,x.h-now,x.ed});
            q2.push((Q){cnt,x.h-now,x.ed});
            cost=c;
        }
    }
    printf("%d\n",ans);
    return 0;
}

  

 

#include<bits/stdc++.h>
using namespace std;
#define ls p<<1
#define rs p<<1|1
#define ll long long
const int N=2e5+10;
struct node {
	int x,y,z;
} a[N];
int k,n,c;
ll maxx[4*N];
ll lazy[4*N];
ll ans;
bool cmp(node x,node y) {
	return x.y<y.y;
}
void update(int p) {
	maxx[p]=max(maxx[ls],maxx[rs]);
}
void push(int p,int l,int r) {
	if(lazy[p]) {
		maxx[ls]+=lazy[p];
		maxx[rs]+=lazy[p];
		lazy[ls]+=lazy[p];
		lazy[rs]+=lazy[p];
		lazy[p]=0;
	}
}
void change(int p,int l,int r,int x,int y,ll val) {
	if(x<=l&&r<=y) {
		maxx[p]+=val;
		lazy[p]+=val;
		return ;
	}
	push(p,l,r);
	int mid=l+r>>1;
	if(x<=mid) change(ls,l,mid,x,y,val);
	if(y>mid) change(rs,mid+1,r,x,y,val);
	update(p);
}
int query(int p,int l,int r,int x,int y) {
	if(x<=l&&r<=y) return maxx[p];
	push(p,l,r);
	int mid=l+r>>1,summ=0;
	if(x<=mid) summ=max(summ,query(ls,l,mid,x,y));
	if(y>mid) summ=max(summ,query(rs,mid+1,r,x,y));
	return summ;
}
int main() {
	scanf("%d%d%d",&k,&n,&c);
	for(int i=1; i<=k; i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
	sort(a+1,a+k+1,cmp);
	for(int i=1; i<=k; i++) {
		int max1=query(1,1,n,a[i].x,a[i].y),res;
		if(max1>=c) continue;
		if(max1+a[i].z<=c) res=a[i].z;
		else res=c-max1;
		ans+=res;
		change(1,1,n,a[i].x,a[i].y-1,res);
	}
	printf("%d\n",ans);
	
	return 0;
}

  

posted @ 2023-12-03 17:39  我微笑不代表我快乐  阅读(31)  评论(0编辑  收藏  举报