P3353 在你窗外闪耀的星星
链接:Miku
-----------------
再见了,我的公主!
-------------------
去除题面,这就是一道线段树板子题,暴力枚举每一个区间然后去最大值就可以了
有星星重叠?本来就是在那个点加上去,继续加就可以了
-------------------
这就是道裸的区间和+单点修改
-----------------------
以及,为了省事,我的线段树直接把右端点搞成了100000,毕竟一堆零没有任何影响
-----------------------
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n,m; long long ans; long long sum[400005], lazy[400005]; int f,x,y; long long k; int rrr; const int maxn=100000; void pushdown(int x, int L, int R){ if (lazy[x] != 0){ int mid = (L + R) >> 1; lazy[x << 1] += lazy[x]; lazy[x << 1 | 1] += lazy[x]; sum[x << 1] += lazy[x] * (mid - L + 1); sum[x << 1 | 1] += lazy[x] * (R - mid); lazy[x] = 0; } return; } void pushup(int x){ sum[x] = sum[x << 1] + sum[x << 1 | 1]; return; } void update(int x, int l, int r, int L, int R, long long d){ if (L <= l && r <= R){ lazy[x] += d; sum[x] += d * (r - l + 1); return; } int mid = (l + r) >> 1; pushdown(x, l, r); if (L <= mid) update(x << 1, l, mid, L, R, d); if (R > mid) update(x << 1 | 1, mid + 1, r, L, R, d); pushup(x); } long long query(int x, int l, int r, int L, int R){ if (L <= l && r <= R){ return sum[x]; } int mid = (l + r) >> 1; pushdown(x, l, r); long long ans = 0; if (L <= mid) ans += query(x << 1, l, mid, L, R); if (R > mid) ans += query(x << 1 | 1, mid + 1, r, L, R); return ans; } int main(){ scanf("%d%d",&n,&m); if(m==0){ cout<<0; return 0; } for(int i=1;i<=n;++i){ scanf("%d%d",&x,&y); update(1, 1,maxn, x, x, y); rrr=max(rrr,x); } rrr-=m; rrr++; for(int i=1;i<=rrr;++i){ ans=max(ans,query(1,1,maxn,i,i+m-1)); } cout<<ans; return 0; }