zoukankan      html  css  js  c++  java
  • [arc082f]Sandglass 递推

    Description

    有一个沙漏由两个上下相通玻璃球A和B构成,这两个玻璃球都含有一定量的沙子,我们暂且假定AB中位于上方的玻璃球的为U,下方的玻璃球为L,则除非U中没有沙子,否则每秒钟都会有1克沙子从U掉入L。

    在第0个时刻,A中有aa克沙子,B中有X−aX−a克沙子(总共有XX克沙子),且U为A,L为B(即A上B下)。

    在r1,r2,...,rKr1,r2,...,rK这些时刻,我们将倒转整个沙漏,使得原来的U变成L,原来的L变成U。对于翻转操作,t时刻是指从第0个时刻起经过t秒后的时刻,我们可以将翻转沙漏的操作看做瞬间完成的。

    现在有Q次询问,每一次询问会给定一对非负整数(ti,ai)(ti,ai),求a=aia=ai,第titi时刻,A中所含沙子的克数。

    Input

    第一行一个正整数XX

    第二行一个正整数KK

    第三行K个整数,表示r1,r2,...,rKr1,r2,...,rK

    接下来一行一个正整数QQ

    接下来QQ行,每行两个非负整数,分别表示每次次询问的(ti,ai)(ti,ai)

    Output

    一共QQ行

    对于每次询问,输出一行一个非负整数表示答案。

    Sample Input

    Sample 1
    180
    3
    60 120 180
    3
    30 90
    61 1
    180 180
    
    Sample 2
    100
    1
    100000
    4
    0 100
    90 100
    100 100
    101 100
    
    Sample 3
    100
    5
    48 141 231 314 425
    7
    0 19
    50 98
    143 30
    231 55
    342 0
    365 100
    600 10
    

    Sample Output

    Sample 1
    60
    1
    120
    
    Sample 2
    100
    10
    0
    0
    
    Sample 3
    19
    52
    91
    10
    58
    42
    100
    

    HINT

    1≤X≤1091≤X≤109

    1≤K≤1051≤K≤105

    1≤r1<r2<...<rK≤1091≤r1<r2<...<rK≤109

    1≤Q≤1051≤Q≤105

    0≤t1<t2<...<tQ≤1090≤t1<t2<...<tQ≤109

    0≤ai≤X(1≤i≤Q)0≤ai≤X(1≤i≤Q)

    所有输入数据均为非负整数

    Sol

    我们发现对于一些连续的起始函数值,到了一定时间会相交。

    我们维护up[i]表示大于等于up[i]的相交,dn[i]表示小于等于dn[i]的相交,dt[i]表示中间区间从开始到现在的相对变化值,然后中间不相交的可以通过线性平移得到。所以对于某个询问,我们找到这个询问前的一个翻转点,判断初始值和updn的关系,确定一个等价的初始值之后加上变化值,加上翻转点到当前时刻的贡献,即为答案。

    dn和up由于单调性,所以可以递推求解。。。注意dn不能大于up。。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    int x,k,q,t,a,mx[100005],mn[100005],dt[100005],rv[100005],ans;
    int main()
    {
        scanf("%d%d",&x,&k);mx[0]=x;mn[0]=0;dt[0]=0;
        for(int i=1;i<=k;i++) scanf("%d",&rv[i]);
        for(int i=1;i<=k;i++)
        {
            mx[i]=mx[i-1];mn[i]=mn[i-1];int tmp=rv[i]-rv[i-1];
            if(i&1) mn[i]=max(mn[i],min(mx[i],tmp-dt[i-1])),dt[i]=max(mn[i-1]+dt[i-1]-tmp,0)-mn[i];
            else mx[i]=min(mx[i],max(mn[i],x-tmp-dt[i-1])),dt[i]=min(mx[i-1]+dt[i-1]+tmp,x)-mx[i];
        }
        for(scanf("%d",&q);q--;printf("%d
    ",ans))
        {
            scanf("%d%d",&t,&a);int pos=upper_bound(rv+1,rv+k+1,t)-rv-1;
            if(a<=mn[pos]) a=mn[pos];else if(a>=mx[pos]) a=mx[pos];
            ans=a+dt[pos];int tmp=t-rv[pos];
            if(pos&1) ans=min(x,ans+tmp);else ans=max(0,ans-tmp);
        }
    }
    
  • 相关阅读:
    flask-离线脚本、with在上下文的应用
    websocket原理及实时投票
    微信消息的推送
    Django + Uwsgi + Nginx 的生产环境部署2
    UVA 11853 Paintball
    UVA 12171 Sculpture
    UVA 10305 Ordering Tasks
    UVA 816 Abbott's Revenge
    UVA 699 The Falling Leaves
    UVA 12657 Boxes in a Line
  • 原文地址:https://www.cnblogs.com/CK6100LGEV2/p/9506923.html
Copyright © 2011-2022 走看看