C32 线段树+贪心 P1607 [USACO09FEB] Fair Shuttle G

视频链接:218 线段树+贪心 [USACO] Fair Shuttle G_哔哩哔哩_bilibili

 

 

Luogu P1607 [USACO09FEB] Fair Shuttle G

复制代码
// 贪心+线段树 O(nlogn)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define ls u<<1
#define rs u<<1|1
const int N=50005;
int n,k,c,ans;
struct line{
  int l,r,m;
  bool operator<(line& b){
    return r<b.r;
  }
}s[N]; //区间
struct tree{
  int l,r,mx,lazy;
}t[N*4]; //线段树

void pushup(int u){ //上传
  t[u].mx=max(t[ls].mx,t[rs].mx);
}
void pushdown(int u){ //下传
  if(t[u].lazy){
    t[ls].mx+=t[u].lazy;
    t[rs].mx+=t[u].lazy;
    t[ls].lazy+=t[u].lazy;
    t[rs].lazy+=t[u].lazy;
    t[u].lazy=0;
  }
}
void build(int u,int l,int r){ //建树
  t[u]={l,r};
  if(l==r) return;
  int mid=l+r>>1;
  build(ls,l,mid);
  build(rs,mid+1,r);
  pushup(u);
}
void change(int u,int l,int r,int v){//区修
  if(l>t[u].r||r<t[u].l) return;
  if(l<=t[u].l&&t[u].r<=r){
    t[u].mx+=v; t[u].lazy+=v;
    return;
  }
  pushdown(u);
  change(ls,l,r,v);
  change(rs,l,r,v);
  pushup(u);
}
int query(int u,int l,int r){ //区查
  if(l>t[u].r||r<t[u].l) return 0;
  if(l<=t[u].l&&t[u].r<=r) return t[u].mx;
  pushdown(u);
  return max(query(ls,l,r),query(rs,l,r));
}
int main(){
  scanf("%d%d%d",&k,&n,&c);
  for(int i=1;i<=k;i++)
    scanf("%d%d%d",&s[i].l,&s[i].r,&s[i].m);
  sort(s+1,s+k+1); //按右端排序
  
  build(1,1,n);
  for(int i=1;i<=k;i++){
    int l=s[i].l,r=s[i].r,m=s[i].m;
    int mx=query(1,l,r-1);
    int x=min(c-mx,m); //能上车的牛数
    change(1,l,r-1,x);
    ans+=x;
  }
  printf("%d",ans);
  return 0;
}
复制代码

 

复制代码
// 贪心+线段树 O(nlogn)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define ls u<<1
#define rs u<<1|1
const int N=50005;
int n,k,c,ans;
struct line{
  int l,r,m;
  bool operator<(line& b){
    return r<b.r;
  }
}s[N];
int mx[N*4],tag[N*4];

void pushup(int u){
  mx[u]=max(mx[ls],mx[rs]);
}
void pushdown(int u){
  if(tag[u]){
    mx[ls]+=tag[u];
    mx[rs]+=tag[u];
    tag[ls]+=tag[u];
    tag[rs]+=tag[u];
    tag[u]=0;
  }
}
void change(int u,int l,int r,int x,int y,int v){
  if(x>r||y<l) return;
  if(x<=l&&r<=y){
    mx[u]+=v; tag[u]+=v;
    return;
  }
  int mid=(l+r)>>1;
  pushdown(u);
  change(ls,l,mid,x,y,v);
  change(rs,mid+1,r,x,y,v);
  pushup(u);
}
int query(int u,int l,int r,int x,int y){
  if(x>r||y<l) return 0;
  if(x<=l&&r<=y) return mx[u];
  int mid=(l+r)>>1;
  pushdown(u);
  return max(query(ls,l,mid,x,y),query(rs,mid+1,r,x,y));
}
int main(){
  scanf("%d%d%d",&k,&n,&c);
  for(int i=1;i<=k;i++)
    scanf("%d%d%d",&s[i].l,&s[i].r,&s[i].m);
  sort(s+1,s+k+1);
  
  for(int i=1;i<=k;i++){
    int l=s[i].l,r=s[i].r,m=s[i].m;
    int mx=query(1,1,n,l,r-1);
    int x=min(c-mx,m);
    change(1,1,n,l,r-1,x);
    ans+=x;
  }
  printf("%d",ans);
  return 0;
}
复制代码

 

复制代码
//暴力维护区间最值,数据很水
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

struct cow{
  int s,e,m; //每组奶牛乘车的起点,终点,数量
  bool operator<(cow &t){
    return e<t.e;
  }
}a[50005];
int b[20005],x,ans;
//b[j]表示经过位置j时车上的奶牛数
//x表示第i组可以上车的奶牛数

int main(){
  int k,n,c; scanf("%d%d%d",&k,&n,&c);
  for(int i=1,x,y,z; i<=k; i++){
    scanf("%d%d%d",&x,&y,&z);
    a[i]={x,y,z};
  }
  sort(a+1,a+k+1); //按终点升序

  for(int i=1;i<=k;i++){
    x=a[i].m; 
    for(int j=a[i].s;j<a[i].e;j++){
      x=min(x,c-b[j]);
      if(x==0) break;
    }
    if(x>0){
      for(int j=a[i].s;j<a[i].e;j++) b[j]+=x;
      ans+=x;
    }
  }
  printf("%d\n",ans);
  return 0;
}
复制代码

 

posted @   董晓  阅读(385)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示