1 条题解

  • 0
    @ 2025-8-24 23:12:52

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar seika27
    1.048596%||秋风扫落叶||哦对了朋友们我已经退役了||R95853||SR6G5-R3XA

    搬运于2025-08-24 23:12:52,当前版本为作者最后更新于2025-05-06 17:05:07,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    思路

    我们考虑将垃圾按 xx 排序,然后维护一个集合,使这个集合中的最大的横坐标之差不大于 WW

    这个集合的维护是简单的,从左往右扫,每次遇到一个新的垃圾就去集合末尾踢掉一些垃圾。由于每个垃圾最多只会被加进集合一次,踢出集合一次,所以复杂度十分的正确。

    那么接下来考虑如何快速计算集合内的答案。

    我们考虑记 lil_i 表示我们能选择的矩形的靠下的那条边纵坐标为 ii 时,能捞到的垃圾重量之和。

    下一步考虑加入一个新的垃圾进入集合,会对哪些 lil_i 产生影响。

    这个很容易就能推出来,当加入了一个纵坐标为 yiy_i 的新垃圾,那么当你的矩形最下面一条边的纵坐标 ii 满足 yiH+1iyiy_i-H+1\leq i \leq y_i 时,你就可以捞到这个垃圾。

    发现这是一个十分简单的区间修改,搞个线段树,发现这个纵坐标有点大,搞个离散化。

    code

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    int n,w,h;
    const int N=1e5+5;
    struct point
    {
    	int x,y,w;
    	int ly,hy;
    }a[N];
    int b[N<<1];
    int tot;
    inline bool operator<(point a,point b)
    {
    	return a.x^b.x?a.x<b.x:a.y^b.y?a.y<b.y:a.w<b.w;
    }
    struct sgt
    {
    	int lar[N<<2],add[N<<2];
    #define lx (x<<1)
    #define rx (x<<1|1)
    #define mid (L+R>>1)
    	inline void up(int x)
    	{
    		lar[x]=max(lar[lx],lar[rx]);
    		return;
    	}
    	inline void tag(int x,int L,int R)
    	{
    		if(add[x])
    		{
    			lar[lx]+=add[x];
    			lar[rx]+=add[x];
    			add[lx]+=add[x];
    			add[rx]+=add[x];
    			add[x]=0;
    		}
    		return;
    	}
    	void update(int x,int L,int R,int l,int r,int v)
    	{
    		if(l<=L&&R<=r){lar[x]+=v,add[x]+=v;return;}
    		tag(x,L,R);
    		if(l<=mid)update(lx,L,mid,l,r,v);
    		if(r>mid)update(rx,mid+1,R,l,r,v);
    		up(x);
    		return;
    	}
    }subaru;
    int ans;
    signed main()
    {
    	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    	cin>>n>>w>>h;
    	for(int i=1;i<=n;++i)cin>>a[i].x>>a[i].y>>a[i].w,b[++tot]=a[i].y,b[++tot]=a[i].y-h+1;
    	sort(a+1,a+1+n);
    	sort(b+1,b+1+tot);
    	tot=unique(b+1,b+1+tot)-b-1;
    	for(int i=1;i<=n;++i)a[i].ly=lower_bound(b+1,b+1+tot,a[i].y-h+1)-b,a[i].hy=lower_bound(b+1,b+1+tot,a[i].y)-b;
    	for(int i=1,j=1;i<=n;++i)
    	{
    		subaru.update(1,1,n,a[i].ly,a[i].hy,a[i].w);
    		while(a[j].x+w-1<a[i].x)subaru.update(1,1,n,a[j].ly,a[j].hy,-a[j].w),++j;
    		ans=max(ans,subaru.lar[1]);
    	}
    	cout<<ans;
    	return 0;
    }
    
    • 1

    [NordicOI 2025] 垃圾收集 / Garbage Collection

    信息

    ID
    11898
    时间
    5500ms
    内存
    1024MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者