rt,我在重构树上倍增要用的 f 数组,不清空就会 WA ON #11,代码中 f 数组应该是每次都会重新计算,不会用到前面几组数据的答案,有没有 dalao 能够解释一下
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define ull unsigned long long
using namespace std;
const int N=2e5+5,M=8e5+5;
const long long LINF=0x3f3f3f3f3f3f3f3fll;
const int IINF=0x3f3f3f3f;
inline void FileIO() {
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
template<typename Type>
inline void read(Type& res) {
Type x=0,f=1;
char c=' ';
while(!isdigit(c)) {
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
res=x*f;
}
int T,n,m,Q,S,K;
int head[N],tot,cnt,num;
int fa[N<<1],val[N<<1],lg[N<<1],dep[N<<1],f[N<<1][25];
ll dis[N<<1],ans;
bool vis[N];
struct Edge{
int to,nxt;
int val,hgt;
}edge[M];
struct Edg2{
int u,v,w;
bool operator<(const Edg2& tmp)const{
return w>tmp.w;
}
}et[M];
vector<int> e[N<<1];
void Clear(){
for(int i=1;i<=num;i++) e[i].clear();
memset(head,0,sizeof(head));
memset(dis,0x3f,sizeof(dis));
memset(dep,0,sizeof(dep));
memset(f,0,sizeof(f));
tot=cnt=num=ans=0;
}
void Add(int u,int v,int w,int h){
edge[++tot].to=v;
edge[tot].nxt=head[u];
edge[tot].val=w;
edge[tot].hgt=h;
head[u]=tot;
}
int GetU(int u){
return (u+K*ans-1)%n+1;
}
int GetP(int p){
return (p+K*ans)%(S+1);
}
int Find(int x){
if(fa[x]==x) return x;
return fa[x]=Find(fa[x]);
}
void Dijkstra(){
priority_queue<pli,vector<pli>,greater<pli> > q;
q.push(make_pair(0,1));
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[1]=0;
while(q.size()){
int x=q.top().second;
q.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=head[x];i;i=edge[i].nxt){
int t=edge[i].to;
if(dis[t]>dis[x]+edge[i].val){
dis[t]=dis[x]+edge[i].val;
q.push(make_pair(dis[t],t));
}
}
}
}
void dfs(int x,int pr){
dep[x]=dep[pr]+1;
f[x][0]=pr;
for(int i=1;i<=lg[dep[x]];i++)
f[x][i]=f[f[x][i-1]][i-1];
for(int t:e[x]) dfs(t,x);
}
void Solve(){
read(n),read(m);
for(int i=1;i<=m;i++){
int u,v,w,h;
read(u),read(v),read(w),read(h);
Add(u,v,w,h);
Add(v,u,w,h);
et[i]={u,v,h};
}
Dijkstra();
sort(et+1,et+m+1); num=n;
for(int i=1;i<=(n<<1);i++) fa[i]=i;
for(int i=1;i<=n;i++) val[i]=INT_MAX;
for(int i=1;i<=m;i++){
int u=et[i].u,v=et[i].v,w=et[i].w;
int fu=Find(u),fv=Find(v);
if(fu==fv) continue;
val[++num]=min({val[fu],val[fu],w});
dis[num]=min(dis[fu],dis[fv]);
fa[fu]=num,fa[fv]=num;
e[num].push_back(fu);
e[num].push_back(fv);
}
dep[0]=-1;
dfs(num,0);
read(Q),read(K),read(S);
while(Q--){
int u,p;
read(u),read(p);
u=GetU(u);
p=GetP(p);
for(int i=lg[dep[u]];i>=0;i--){
if(val[f[u][i]]>p)
u=f[u][i];
}
// printf("U=%d\n",u);
ans=dis[u];
printf("%lld\n",dis[u]);
}
}
signed main(){
// 不开longlong见祖宗!
// 检查数组大小!
// 禁止在int乘int时不开longlong!
// 注意输出格式!
// STL数据类型拷贝赋值时间复杂度是 O(N)!
// 读入单个字符要用字符串,防毒瘤数据!
// (1<<63)爆ll,(1<<31)爆int!
// 比赛结束前5min,检查上述7项,并编译运行!!!!!
// -std=c++14 -O2 -Wall -Wextra -Wshadow -Wl,--stack=536870912
read(T);
for(int i=2;i<=400000;i++)
lg[i]=lg[i>>1]+1;
while(T--){
Solve();
Clear();
}
return 0;
}