首页 > 其他分享 >P05527 [Usaco2009 Feb]庙会捷运加强版

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

时间:2023-12-03 17:59:33浏览次数:37  
标签:include Feb 加强版 int ans cost mp 捷运 now

庙会捷运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;
}

  

标签:include,Feb,加强版,int,ans,cost,mp,捷运,now
From: https://www.cnblogs.com/cutemush/p/17873476.html

相关文章

  • [USACO23FEB] Equal Sum Subarrays G 题解
    [USACO23FEB]EqualSumSubarraysG题解题目链接\(O(n^5)\)暴力显然,如果修改\(a_i\)的值,只会影响包含\(a_i\)的区间的区间和。于是对于每个\(a_i\),可以将所有区间分成两类,即包含\(a_i\)的区间和不包含\(a_i\)的区间。这两种区间的区间和中最小的差值即为答案。......
  • 洛谷 P9129 [USACO23FEB] Piling Papers G
    第一问是简单的,\(2(n-1)-[T=1]\cdot\max\limits_{i=1}^{n}\{dep_i\}\)。对于第二问:设\(f(u)\)表示要求起点和终点均为\(u\)的情况下从\(1\)时刻开始遍历完以\(u\)为根的子树的最小花费,\(g(u)\)表示要求起点为\(u\),重点深度最大的情况下从\(1\)时刻开始遍......
  • jUnit测试框架入门详解​(加强版)
    jUnit测试框架入门详解入门知识什么是单元测试单元测试是针对最小的功能单元编写的测试代码。Java程序最小的功能单元是方法,因此单元测试就是针对单个Java方法的测试。为什么要使用单元测试使用main()方法测试的缺点:只能有一个main()方法,不能把测试代码分离,且也没有打印出测试结果......
  • 题解 LOJ3483【[USACO21FEB] Counting Graphs P】
    题解P7418【[USACO21FEB]CountingGraphsP】problemBessie有一个连通无向图\(G\)。\(G\)有\(N\)个编号为\(1\ldotsN\)的结点,以及\(M\)条边(\(1\leN\le10^2,N-1\leM\le\frac{N^2+N}{2}\))。\(G\)有可能包含自环(一个结点连到自身的边),但不包含重边(连接同一对结点......
  • P2895 [USACO08FEB] Meteor Shower S
    P2895[USACO08FEB]MeteorShowerS语言问题引发的惨案题目本身不难,简单的BFS,但是写出来明明思路感觉没有问题,却不是答案错就是爆队列。#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<queue>usingnamespacestd;structNode......
  • 洛谷 P8192 - [USACO22FEB] Paint by Rectangles P
    比较抽象的一个题。首先先考虑\(T=1\),如果我们建一张图,将图上所有横线与竖线的交点看作图上的点,相邻的有线段相连的点看作图上的边的话,那么显然会得到一张平面图,而我们要计算的是平面图上面的个数,根据公式\(F=E-V+C+1\),其中\(C\)为这张图中连通块的个数。设\(c\)为线段与线......
  • [USACO08FEB]meteor Shower S题解(bfs)
    题目描述贝茜听说一场特别的流星雨即将到来:这些流星会撞向地球,并摧毁它们所撞击的任何东西。她为自己的安全感到焦虑,发誓要找到一个安全的地方(一个永远不会被流星摧毁的地方)。如果将牧场放入一个直角坐标系中,贝茜现在的位置是原点,并且,贝茜不能踏上一块被流星砸过的土地。根据预......
  • [POI2014] HOT-Hotels 加强版
    [POI2014]HOT-Hotels题面翻译给定一棵树,在树上选\(3\)个点,要求两两距离相等,求方案数。题目描述Thereare\(n\)townsinByteotia,connectedwithonly\(n-1\)roads.Eachroaddirectlylinkstwotowns.Alltheroadshavethesamelengthandaretwoway.Itis......
  • P4824 [USACO15FEB] Censoring S
    P4824[USACO15FEB]CensoringSKMP+栈同样的套路,先找B的最长前后缀,然后与A匹配不同的是要删除A中的B,特殊的是删除之后可能会产生新的B那我们可以利用栈的思想,利用f数组,记录A每一位置上B的匹配程度,这样删除时,直接回到上一个匹配程度,以防漏掉。利用栈记录下标,还在栈内的,说明......
  • P7414 [USACO21FEB] Modern Art 3 G 题解
    思路考虑区间DP。设\(f_{i,j}\)表示要刷到\([i,j]\)这一段的目标需要的最小次数。对于\(f_{i,j}\),如果\(color_i\)与\(color_j\)相等,那么再子区间合并的时候就可以少刷一次,即\(f_{i,j}=\min\limits_{k=i}^{j-1}f_{i,k}+f_{k+1,j}-1\)。否则\(f......