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;
}

浙公网安备 33010602011771号