题目大意:
你从起点走到终点,中间有很多的红绿灯,遇到红灯不能走,要等到绿灯。红灯和绿灯都是固定的G,R时间。你会从T时刻出发,问到达终点的时间是什么时候。
思路:
这题和2018 GDKOI T1差不多..算法虽然不同,但是他的思路是差不多的。走到一个红灯,后面需要走的时间就是一个固定的常数了,所以只需要求出遇到第一个红灯需要的时间,以及每个点为0时刻出发到终点的时间。
我们讨论如何找第一个红灯。预处理同理。
我们发现当T%(G+R)在区间[G,G+R]的时候就会遇到红灯。所以我们只要维护一个在区间里面编号最小的值,因为G,R比较大,所以不能暴力维护,要用权值线段树离散。
程序:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define N 50005
#define inf 0x3f3f3f3f
using namespace std;
int ls[N*2],rs[N*2],val[N*2];
LL d[N],f[N],sum[N],b[N],c[N];
LL g,r;
int n,q,rt,cnt,m;
void ins(int &x,int l,int r,int pos,int w){
if (!x) x=++cnt;
if (l==r) {val[x]=min(val[x],w); return;}
int mid=(l+r)>>1;
if (pos<=mid) ins(ls[x],l,mid,pos,w);
else ins(rs[x],mid+1,r,pos,w);
val[x]=min(val[ls[x]],val[rs[x]]);
}
int qry(int x,int l,int r,int l1,int r1){
if (!x||l1>r1) return inf;
if (l>=l1&&r<=r1) return val[x];
LL mid=(l+r)>>1;
int ret=inf;
if (l1<=mid) ret=qry(ls[x],l,mid,l1,r1);
if (r1>mid) ret=min(ret,qry(rs[x],mid+1,r,l1,r1));
return ret;
}
int main(){
freopen("light.in","r",stdin);
freopen("light.out","w",stdout);
memset(val,0x3f,sizeof(val));
scanf("%d%lld%lld",&n,&g,&r);
for (int i=1;i<=n+1;++i) scanf("%lld",d+i);
for (int i=1;i<=n+1;++i) sum[i]=sum[i-1]+d[i],c[i]=b[i]=sum[i]%(g+r);
c[n+2]=0; c[n+3]=g+r;
sort(c+1,c+n+4);
m=unique(c+1,c+n+4)-c-1;
for (int i=n;i>=1;--i){
int p;
LL lc=(b[i]+g)%(g+r),rc=(g+r-1+b[i])%(g+r);
int l1=lower_bound(c+1,c+m+1,lc)-c;
int r1=upper_bound(c+1,c+m+1,rc)-c-1;
if (lc<=rc) p=qry(rt,1,m,l1,r1);
else p=min(qry(rt,1,m,l1,m),qry(rt,1,m,1,r1));
if (p<inf) f[i]=sum[p]-sum[i]+g+r-(sum[p]-sum[i])%(g+r)+f[p];
else f[i]=sum[n+1]-sum[i];
ins(rt,1,m,lower_bound(c+1,c+m+1,b[i])-c,i);
}
scanf("%d",&q);
while (q--){
LL t,y; int p;
scanf("%lld",&t); y=(g+r-t%(g+r))%(g+r);
LL lc=(y+g)%(g+r),rc=(g+r-1+y)%(g+r);
int l1=lower_bound(c+1,c+m+1,lc)-c;
int r1=upper_bound(c+1,c+m+1,rc)-c-1;
if (lc<=rc) p=qry(rt,1,m,l1,r1);
else p=min(qry(rt,1,m,l1,m),qry(rt,1,m,1,r1));
if (p<inf) printf("%lld\n",sum[p]+f[p]+g+r-(sum[p]+t)%(g+r)+t);
else printf("%lld\n",sum[n+1]+t);
}
return 0;
}