1 条题解
-
0
自动搬运
来自洛谷,原作者为

WAMonster
这个人懒死了搬运于
2025-08-24 22:06:19,当前版本为作者最后更新于2018-11-17 20:24:15,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
NOIP后趁还没出成绩发一篇水题题解。
首先,我们发现当仅有一人落水时,这题的水位增长如果看成一条曲线的话,其增减是线性的。也就是说水位线的变化在图上画出来是一条折线。它长这样:

(如图表示一个的人在处落水后的新水位)
这不珂学!!!水怎么还多了!!!既然它递增/递减是均匀的,那么我们可以考虑先用差分维护某一点的水位与上一点的差值,很显然维护的差值也是一个差分。差分还原成原值需要求前缀和,所以第一次差分之后跑两遍前缀和即可。
这里只列举一人落水的情况,但手玩数据可发现,随便多少人都一样。
绿题貌似有点高估了此题难度?注意落水处左边的坐标值可以为负。开两倍数组再搞个指针即可。
code:
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,m; int aa[2100000],bb[2100000]; #define isdigit(x) ((x)>='0'&&(x)<='9') inline int read(){ int a=0,flag=1; char c=getchar(); while(!isdigit(c)){ if(c=='-')flag=-1; c=getchar(); } while(isdigit(c)){ a=(a<<1)+(a<<3)+c-48; c=getchar(); } return a*flag; } int main(){ n=read(),m=read(); int *a=aa+1000000,*b=bb+1000000; for(int i=1;i<=n;++i){ int v=read(),x=read(); a[x-3*v+1]++; a[x-2*v+1]-=2; a[x+1]+=2; a[x+2*v+1]-=2; a[x+3*v+1]++; } for(int i=-40000;i<=m+40000;++i)a[i]+=a[i-1],b[i]+=b[i-1]+a[i]; for(int i=1;i<=m;++i)printf("%d ",b[i]); return 0; }
- 1
信息
- ID
- 3788
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者