博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【AtCoder】ARC082 F - Sandglass
阅读量:6688 次
发布时间:2019-06-25

本文共 1248 字,大约阅读时间需要 4 分钟。

【链接】

【题意】给定沙漏A和B,分别装着a和X-a的沙子,开始时A在上B在下,每秒漏1,漏完不再漏。给定n,有n个时刻ai沙漏倒转。给定m个询问,每次询问给定初值a和时刻t,求A中沙子量。

【算法】数学(函数)

【题解】

先不考虑时刻,令ft(a)表示沙子初值a时,当前A中的沙子数。(x轴是初值a,y轴是沙子数num)

时刻为0时,显然是一条从0出发斜率为1的直线。

若A在上,则每过1s,整段函数都下移一个单位,碰到y=0则变成平的。

若A在下,则每过1s,整段函数都上移一个单位,碰到y=X则变成平的。

而不平的部分,斜率恒为1

这样,这个函数始终是一个三段函数,可以按时间顺序维护两个转折点的位置就可以快速出解。

复杂度O(m)。

然而这个函数还有一些特殊的性质,所以可以更方便地写程序。

我们维护斜率为1的原y=x+b,其中b就是变化量,这样f(A)就是A+b,判断一下A+b和两个转折点y值的关系即可。

#include
#include
#include
using namespace std;const int maxn=100010;int n,m,a[maxn];int calc(int l,int r,int x){
return max(l,min(r,x));}int main(){ int X; scanf("%d%d",&X,&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); int L,R=X;//初值…… int t=0,k=0,s=-1,x=0; int time,A; scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%d%d",&time,&A); while(k
<=time){ int dif=s*(a[k+1]-t); L=calc(0,X,L+dif); R=calc(0,X,R+dif); s*=-1; x+=dif; t=a[k+1]; k++; } int T=time-t; A=calc(L,R,A+x); A=calc(0,X,A+s*T); printf("%d\n",A); } return 0;}
View Code

 

转载于:https://www.cnblogs.com/onioncyc/p/7492765.html

你可能感兴趣的文章
面试总结,坚定自己的想法
查看>>
数据库隐式类型转换
查看>>
解决WCF调用多次之后没有响应的问题 转
查看>>
【BZOJ2318】【spoj4060】game with probability Problem 概率DP
查看>>
空格&amp;nbsp在不同浏览器中显示距离不一致问题解决方法
查看>>
Nancy 学习-身份认证(Basic Authentication) 继续跨平台
查看>>
分享5个主流的HTML5开发工具
查看>>
基于Ionic2的开源项目
查看>>
QEMU-KVM中的多线程压缩迁移技术
查看>>
Android下创建一个SQLite数据库
查看>>
软件产品与代码版本管理指南
查看>>
分析Linux内核创建一个新进程的过程【转】
查看>>
sql如何分组选择显示最新的一条数据
查看>>
周锦民:腾讯在线教育视频互动直播间技术实践
查看>>
[perl] 正则表达式实现多模式匹配
查看>>
class左边nbu 2414 Please help the poor donkey!
查看>>
[转]UML类图、关系及其JAVA代码
查看>>
PhotoShop算法原理解析系列 - 像素化---》碎片。
查看>>
设计模式之责任链模式
查看>>
在 Windows 下安装 Oracle 11g XE (Express Edition)
查看>>