zoukankan      html  css  js  c++  java
  • [arc082F]Sandglass

    Description

    传送门

    Solution

    这题是真的666啊。。。

    以下是本题最关键最关键的结论:如果ai<=aj,则在某个时间t,前者的A中沙子克数(记为t(ai))一定大于等于t(aj)。证明显然。

    假设我们目前处理到到询问为(t,a),设ri为满足ri<=t的最大值。我们要处理三个量:

    1,时刻ri,在不考虑限制(即不考虑沙子数只能为[0,X]范围,它可能比X大,也可能比0小)的情况下,相对于初始时的沙子数变化c。

    2,时刻ri,初始A中沙子为0情况下的沙子数down。

    3,时刻ri,初始沙子为X情况下的沙子数up。

    经过分析,沙子数a加减的过程有4中情况(以下情况的沙子数都是指A中的)。

    1:a没有被“沙子数只能为[0,X]范围”这个条件限制过。

    2:a只被“沙子数必须<=X”条件限制过。

    3:a只被“沙子数必须>=0”条件限制过。

    4:a被“沙子数必须>=0”和“沙子数必须<=X”两个条件都限制过。

    此处的"限制过"是指在计算到某一步的时候,沙子数量达到极限以至于不会再从上往下掉落。从数学的角度看(以条件沙子数必须>=0为例),即为:a-(r[k]-r[k-1])<0,但由于题目要求,a必须=0。

    在最终判断答案的时候,询问(t,a)在时刻ri沙子数的式子为max(down,min(up,a+c))。

    证明:

    情况1中,由于本题结论并且0<=a<=X,可得a+c<=up,a+c>=down,式子答案为a+c,又因为a没有被限制过,所以该答案正确。

    情况2中,假设在时刻t0,a被限制,即t0(a)=X,又因为本题结论,t0(a)<=t0(X),则t0(X)=X。在这一时刻t0(a)=t0(X),正确答案即为up。由于a+c是不受限制(沙子数>=X)的结果,所以a+c>=up。即min(up,a+c)=up,up>=down,式子答案为up,正确。

    情况3同理;

    情况4由于t(a)=up=down,不论a+c与t(up)的大小关系如何都正确。

    求出(ri,a)后,记录一下接下来应该加还是减,直接操作便可得出(t,a)。

    所以我们只需要把询问按时间排个序扫一遍就过啦。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int X,k,r[100010],Q;
    struct node{int t,a,id;
    }q[100010];int ans[100010];
    bool cmp(node x,node y) {return x.t<y.t;}
    int pls(int x,int y){return max(0,min(X,x+y));}
    int main()
    {
        scanf("%d%d",&X,&k);
        for (int i=1;i<=k;i++) scanf("%d",&r[i]);
        scanf("%d",&Q);
        for (int i=1;i<=Q;i++) 
        {
            scanf("%d%d",&q[i].t,&q[i].a);q[i].id=i;
        }
        sort(q+1,q+Q+1,cmp);
        int topr=0,topq=1,sum=0,down=0,up=X,add=0,js=-1;
        int cnt;
        while (topq<=Q)
        {
            if (r[topr+1]<q[topq].t&&topr<k)
            {
                topr++;
                add=js*(r[topr]-r[topr-1]);
                down=pls(down,add);up=pls(up,add);
                sum+=add;js=-js;
            } else
            {
                cnt=q[topq].t-r[topr];
                ans[q[topq].id]=pls(max(down,min(up,q[topq].a+sum)),js*cnt);
                topq++;
            }
        }
        for (int i=1;i<=Q;i++) printf("%d
    ",ans[i]);
        
    } 
  • 相关阅读:
    P1012拼数
    P1622释放囚犯
    P1064 金明的预算方案
    P1754球迷购票问题
    卡塔兰数
    P1474货币系统
    P2562kitty猫基因
    P3984高兴的津津
    5-servlet简介
    java通过百度AI开发平台提取身份证图片中的文字信息
  • 原文地址:https://www.cnblogs.com/coco-night/p/9495040.html
Copyright © 2011-2022 走看看