AtCoderARC082 F - Sandglass

Posted ONION_CYC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoderARC082 F - Sandglass相关的知识,希望对你有一定的参考价值。

【链接】F - Sandglass

【题意】给定沙漏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)。

 

 

技术分享
#include<cstdio>
#include<algorithm>
#include<cstring>
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<n&&a[k+1]<=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

 

以上是关于AtCoderARC082 F - Sandglass的主要内容,如果未能解决你的问题,请参考以下文章

AtCoderARC096(C - F)

AtCoderARC067 F - Yakiniku Restaurants 单调栈+矩阵差分

AtCoderARC099 F - Eating Symbols Hard

AtCoder ARC 082E - ConvexScore

AtCoderARC100 题解

AtCoderARC089