ARC082 F Sandglass - 乱搞

考虑对于每个时刻p,维护当a在L[p]和R[p]变动的时候,ans[p]变动也是连续的。
这个其实真心很好维护,然后就没了。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#define P(a,y) a=min(x,max(0,y+dlt[i]))
#define INF (INT_MAX/2)
#define gc getchar()
#define N 100010
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
inline int inn()
{
    int x,ch;while((ch=gc)<'0'||ch>'9');
    x=ch^'0';while((ch=gc)>='0'&&ch<='9')
        x=(x<<1)+(x<<3)+(ch^'0');return x;
}
int s[N],dlt[N],r[N],ans_0[N],ans_x[N],xs[5],L[N],R[N];
inline int getpos(int t,int n)
{
    int L=1,R=n,mid=(L+R)>>1;
    while(L<=R)
    {
        if(r[mid]<=t) L=mid+1;
        else R=mid-1;mid=(L+R)>>1;
    }
    return R;
}
char ss[N*15],tt[20];int ssl,ttl;
inline int show(int x)
{
    if(!x) return ss[++ssl]='0',ss[++ssl]='\n';
    for(ttl=0;x;x/=10) tt[++ttl]=x%10+'0';
    for(;ttl;ttl--) ss[++ssl]=tt[ttl];
    return ss[++ssl]='\n';
}
int main()
{
    int x=inn(),n=inn();
    for(int i=1;i<=n;i++) r[i]=inn();r[++n]=INF;
    xs[0]=1,xs[1]=-1,ans_0[0]=L[0]=0,ans_x[0]=R[0]=x;
    for(int i=1;i<=n;i++)
        dlt[i]=xs[i&1]*(r[i]-r[i-1]),s[i]=s[i-1]+dlt[i],
        L[i]=max(L[i-1],0-s[i]),R[i]=min(R[i-1],x-s[i]),
        P(ans_0[i],ans_0[i-1]),P(ans_x[i],ans_x[i-1]);
    for(int q=inn();q;q--)
    {
        int t=inn(),a=inn(),p=getpos(t,n),ans=0;
        if(a<=L[p]) ans=ans_0[p];
        else if(a>=R[p]) ans=ans_x[p];
        else ans=s[p]+a;
        show(min(max(ans-xs[p&1]*(t-r[p]),0),x));
    }
    return fwrite(ss+1,sizeof(char),ssl,stdout),0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值