[bzoj5142][Usaco2017 Dec]Haybale Feast

Orz w_yqts
在某王姓dalao的指导下暂时卡到rank1……Orz
二分答案

#include 
#define ll long long
#define N 100001
inline int read()
{
    char ch=getchar();
    int x=0;
    while ('0'>ch || ch>'9') ch=getchar();
    while ('0'<=ch && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x;
}
ll m;
int a[N],b[N],n,l=0,r=1e9,mid;
inline bool check()
{
    ll t=0LL;
    for (int i=1;i<=n;++i)
    {
        if (b[i]>mid) {t=0;continue;}
        t+=a[i];
        if (t>=m) return 1;
    }
    return 0;
}
int main()
{
    n=read();scanf("%lld",&m);
    for (int i=1;i<=n;++i) a[i]=read(),b[i]=read();
    while (l>1;
        if (check()) r=mid;else l=mid+1;
    }
    printf("%d\n",l);
}

并查集合并

#include 
#include 
#define ll long long
#define N 100001
inline int read()
{
    char ch=getchar();
    int x=0;
    while ('0'>ch || ch>'9') ch=getchar();
    while ('0'<=ch && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x;
}
struct node
{
    int x,y,id;
}a[N];
bool cmp(node x,node y)
{
    return x.y.y;
}
ll m,s[N];
int f[N],n,flag[N];
inline int find(int x)
{
    if (f[x]==x) return x;
    f[x]=find(f[x]);
    return f[x];
}
inline void merge(int x,int y)
{
    x=find(x);y=find(y);
    s[x]+=s[y];
    f[y]=x;
}
int main()
{
    n=read();scanf("%lld",&m);
    for (int i=1;i<=n;++i) a[i]={read(),read()},a[i].id=f[i]=i,s[i]=a[i].x;
    std::sort(a+1,a+1+n,cmp);
    for (int i=1;i<=n;++i)
    {
        int id=a[i].id;
        flag[id]=1;
        if (flag[id-1]) merge(id,id-1);
        if (flag[id+1]) merge(id,id+1);
        if (s[find(id)]>=m) {printf("%d\n",a[i].y);return 0;}
    }
}

单调队列

#include 
#define ll long long
#define N 100005
inline int read()
{
    char ch=getchar();
    int x=0;
    while ('0'>ch || ch>'9') ch=getchar();
    while ('0'<=ch && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x;
}
inline int min(int x,int y)
{
    return x<y?x:y;
}
ll m,s;
int a[N],b[N],q[N],n,ans=1e9;
int main()
{
    n=read();scanf("%lld",&m);
    for (int i=1;i<=n;++i) a[i]=read(),b[i]=read();
    int last=0,st=1,ed=0;
    for (int i=1;i<=n;++i)
    {
        while (st<=ed && q[st]s-=a[i-1];
        while (s<m && lasts+=a[++last];
            while (b[last]>=b[q[ed]] && st<=ed) --ed;
            q[++ed]=last;
        }
        if (s<m) break;
        ans=min(ans,b[q[st]]);
    }
    printf("%d\n",ans);
}

你可能感兴趣的:([bzoj5142][Usaco2017 Dec]Haybale Feast)