感觉其实今天 \(B\) 是最有趣的,难度估在上位紫吧。
一眼数学,两眼不是数学,三眼发现可以让 \(x\) 向 \((dx+t)\bmod n\ (t\in[L,R])\) 连边,然后从每个 \(x\) 找到到根最短路径。对于每个给出的 \(x'\),它所覆盖的范围是 \([x'+L,x'+R]\),可以用滑动窗口 \(O(n)\) 求解。时间复杂度 \(O(tn^3)\),劣得要死,考虑优化。
发现我们刚才说的问题实际上是多点到一点,显然可以建反图,这样就只需要从 \(0\) 出发跑一遍 \(BFS\),时间复杂度 \(O(tn^2)\)。
区间到单点,想到线段树优化建图,只需要把 \(BFS\) 换成 \(01BFS\) 即可,时间复杂度 \(O(tn\log n)\)。再想用优化建图的思路做就只能用分块了。发现每个向单点连边的区间长度都为 \(R-L+1\),那么假如设块长为 \(R-L+1\),那么我们就可以把区间分割成 \(O(1)\) 个块的前后缀,就可以分块优化建图了,时间复杂度 \(O(tn)\),卡常后可过。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5,M=3e6+5;
const int bufsz = 1 << 20;
char ibuf[bufsz], *p1 = ibuf, *p2 = ibuf;
char obuf[bufsz], *p3 = obuf, stk[50];
#define getchar() (p1 == p2 && (p2 = (p1 = ibuf) + fread(ibuf, 1, bufsz, stdin), p1 == p2) ? EOF : *p1++)
#define flush() (fwrite(obuf, 1, p3 - obuf, stdout), p3 = obuf)
#define putchar(ch) (p3 == obuf + bufsz && flush(), *p3++ = (ch))
inline int read() {int x = 0; char ch = getchar();while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}return x;
}inline void write(int x, bool t = 1) {int top = 0;x < 0 ? putchar('-'), x = -x : 0;do {stk[++top] = x % 10 | 48; x /= 10;} while(x);while(top) putchar(stk[top--]);t ? putchar('\n') : putchar(' ');
}struct FL {~FL() {flush();}} fld;
#undef getchar()
#undef putchar()
#undef flush()
struct edge{int to,cs;}ed[N*7];int nx[N*7];int q[N*6],fsd,edd;
int t,k,n,d,lc,rc,Q,dis[M],vis[M],as[N],h[M],qc[N*2],fsq,edq,fl=1;
inline void adde(int x,int y,int w){nx[++k]=h[x],ed[h[x]=k]={y,w};
}inline void build(){for(int i=0;i<n;i++) adde(i,i+n,0),adde(i,i+2*n,0);for(int i=0;i<n-1;i++) if(i/(rc-lc+1)==(i+1)/(rc-lc+1))adde(i+n,i+n+1,0),adde(i+2*n+1,i+2*n,0);
}inline void add(int l,int r,int to){if(l%(rc-lc+1)==0) adde(r+n,to,1);else if(r==n-1&&l/(rc-lc+1)==r/(rc-lc+1)) adde(l+2*n,to,1);else adde(r+n,to,1),adde(l+2*n,to,1);
}inline void bfs01(){for(int i=1;i<3*n;i++) dis[i]=1e9;q[fsd=edd=3*n]=0;while(fsd<=edd){int x=q[fsd++];if(vis[x]) continue;vis[x]=1;for(int i=h[x];i;i=nx[i]){if(dis[ed[i].to]>dis[x]+ed[i].cs){dis[ed[i].to]=dis[x]+ed[i].cs;if(ed[i].cs) q[++edd]=ed[i].to;else q[--fsd]=ed[i].to;}}}
}inline int chg(int x){return x==1e9?-1:x;}
inline void insert(int x){while(fsq<=edq&&dis[qc[edq]]>dis[x]) --edq;qc[++edq]=x;
}inline void solve(){for(int i=0;i<3*n;i++) h[i]=vis[i]=0;n=read(),d=read(),lc=read();rc=read(),Q=read(),k=0,build();for(int i=1;i<n;i++){int lk=(1ll*i*d+lc)%n,rk=(1ll*i*d+rc)%n;if(lk<=rk) add(lk,rk,i);else add(0,rk,i),add(lk,n-1,i);}bfs01(),fsq=1,edq=0;for(int i=lc;i<=rc;i++)insert(i);as[0]=chg(dis[qc[fsq]]);for(int i=1;i<n;i++){if(qc[fsq]==i+lc-1+(i+lc-1>=n?-n:0)) ++fsq;insert(i+rc+(i+rc>=n?-n:0)),as[i]=chg(dis[qc[fsq]]);}while(Q--) write(as[read()]);
}int main(){freopen("calculate.in","r",stdin);freopen("calculate.out","w",stdout);t=read();while(t--) solve();return 0;
}