求调
查看原帖
求调
718667
zhaomumu1218楼主2024/8/23 15:35
#include<bits/stdc++.h>
using namespace std;
int n,m,rt[1000010],cnt,dis[200010];
struct node{
    int fa,ls,rs,deep,minn;
}t[6000010];
int build(int l,int r){
    int u=++cnt;
    if(l==r){
        t[u].fa=l;
        t[u].minn=dis[l];
        return u;
    }
    int mid=(l+r)/2;
    t[u].ls=build(l,mid);
    t[u].rs=build(mid+1,r);
    return u;
}
int query(int u,int l,int r,int x){
    if(l==r) return u;
    int mid=(l+r)/2;
    if(mid>=x) return query(t[u].ls,l,mid,x);
    else return query(t[u].rs,mid+1,r,x);
}
int find_root(int u,int a){
    int fa=query(rt[u],1,n,a);
    if(t[fa].fa==a) return fa;
    return find_root(u,t[fa].fa);
}
int marge(int u,int l,int r,int x,int f){
    int d=++cnt;
    t[d]=t[u];
    if(l==r){
        t[d].fa=f;
        return d;
    }
    int mid=(l+r)/2;
    if(mid>=x) t[d].ls=marge(t[u].ls,l,mid,x,f);
    else t[d].rs=marge(t[u].rs,mid+1,r,x,f);
    t[d].minn=min({t[d].minn,t[t[d].ls].minn,t[t[d].rs].minn});
    return d;
}
int add(int u,int l,int r,int x){
    int d=++cnt;
    t[d]=t[u];
    if(l==r){
        t[d].deep++;
        return d;
    }
    int mid=(l+r)/2;
    if(mid>=x) t[d].ls=add(t[u].ls,l,mid,x);
    else t[d].rs=add(t[u].rs,mid+1,r,x);
    t[d].minn=min({t[d].minn,t[t[d].ls].minn,t[t[d].rs].minn});
    return d;
}
void merge(int u,int a,int b){
    rt[u]=rt[u-1];
    a=find_root(u,a),b=find_root(u,b);
    if(t[a].fa!=t[b].fa){
        if(t[a].deep>t[b].deep) swap(a,b);
        rt[u]=marge(rt[u-1],1,n,t[a].fa,t[b].fa);
        if(t[a].deep==t[b].deep) rt[u]=add(rt[u],1,n,t[b].fa);
    }
}
struct nodee{
    int u,v,l,a;
    bool operator<(const nodee t)const{
        return a>t.a;
    }
}no[400010];
vector<pair<int,int> >e[200010];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
bool flag[200010];
void dij(){
    memset(dis,0x3f,sizeof(dis));
    memset(flag,0,sizeof(flag));
    dis[1]=0;
    q.push({0,1});
    while(!q.empty()){
        int u=q.top().second;
        q.pop();
        if(flag[u]) continue;
        flag[u]=1;
        for(auto v:e[u]) if(dis[v.first]>dis[u]+v.second){
            dis[v.first]=dis[u]+v.second;
            q.push({dis[v.first],v.first});
        }
    }
}
void solve(){
    memset(t,0,sizeof(t));
    for(int i=1;i<=6000000;i++) t[i].minn=INT_MAX;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) e[i].clear();
    for(int i=1;i<=m;i++){
        scanf("%d%d%d%d",&no[i].u,&no[i].v,&no[i].l,&no[i].a);
        e[no[i].u].push_back({no[i].v,no[i].l});
        e[no[i].v].push_back({no[i].u,no[i].l});
    }
    dij();
    cnt=0;
    rt[0]=build(1,n);
    sort(no+1,no+1+m);
    for(int i=1;i<=m;i++){
        rt[i]=rt[i-1];
        int u=find_root(i,no[i].u),v=find_root(i,no[i].v);
        if(u==v) continue;
        merge(i,u,v);
    }
    int q,k,s,lastans=0;
    scanf("%d%d%d",&q,&k,&s);
    for(int i=1;i<=q;i++){
        int v,p; 
        scanf("%d%d",&v,&p);
        v=(v+k*lastans-1)%n+1;
        p=(p+k*lastans)%(s+1);
        int l=0,r=m,ans=0;
        while(l<=r){
            int mid=(l+r)/2;
            if(no[mid].a>p) l=mid+1,ans=mid;
            else r=mid-1;
        }
        if(ans==0){
            printf("%d\n",lastans=dis[v]);
            continue;
        }
        if(l==m+1){
            printf("%d\n",lastans=0);
            continue;
        }
        // printf("!%d!",t[find_root(ans,v)].minn);
        printf("%d\n",(lastans=t[find_root(ans,v)].minn));
    }
}
signed main(){
    int T;
    scanf("%d",&T);
    while(T--) solve();
    return 0;
}
2024/8/23 15:35
加载中...