求助,可持久化并查集,不知道哪里错了。
查看原帖
求助,可持久化并查集,不知道哪里错了。
194093
天梦楼主2021/10/30 15:27
#include<bits/stdc++.h>
#define dd double
#define ld long double
#define ll long long
// #define int long long
#define uint unsigned int
#define ull unsigned long long
#define N 600010
#define M number
using namespace std;

const int INF=0x3f3f3f3f;

template<typename T> inline void read(T &x) {
    x=0; int f=1;
    char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c == '-') f=-f;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    x*=f;
}

template<typename T> inline T Min(T a,T b){return a<b?a:b;}

struct edge{
    int from,to,next,w,High;
    inline void Init(int fr_,int to_,int ne_,int w_,int h_){from=fr_;to=to_;next=ne_;w=w_;High=h_;}
    inline bool operator < (const edge &b)const{return High>b.High;}
}li[N<<2];
int head[N],tail;

inline void Add(int from,int to,int w,int High){
    li[++tail].Init(from,to,head[from],w,High);
    head[from]=tail;
}

int n,m;

struct Node{
    int ls,rs;
}p[N];
int tot;
int Root[N],fa[N*40],Dep[N*40],MinDis[N*40],rtt;
int Hi[N],d[N],Q,K,S;
ll Ans;
bool vis[N];

#define ls(k) p[k].ls
#define rs(k) p[k].rs
struct DSU{
    inline int NewNode(){return ++tot;}
    inline void Build(int &k,int l,int r){
        k=NewNode();
        if(l==r){fa[k]=l;MinDis[k]=d[l];return;}
        int mid=(l+r)>>1;Build(ls(k),l,mid);Build(rs(k),mid+1,r);
    }
    inline int GetPosi(int k,int l,int r,int w){
        if(l==r) return k;
        int mid=(l+r)>>1;
        if(w<=mid) return GetPosi(ls(k),l,mid,w);
        else return GetPosi(rs(k),mid+1,r,w);
    }
    inline int Find(int k,int x){
        // printf("k=%d x=%d\n",k,x);
        int now=GetPosi(k,1,n,x);
        // printf("now=%d\n",now);
        // printf("fa[%d]=%d\n",now,fa[now]);
        if(fa[now]==x) return now;
        else return Find(k,fa[now]);
    }
    inline void Change(int &k,int last,int l,int r,int w,int x){
        k=NewNode();
        p[k]=p[last];
        if(l==r){
            Dep[k]=Dep[last];fa[k]=x;MinDis[k]=MinDis[last];
            return;
        }
        int mid=(l+r)>>1;
        if(w<=mid) Change(ls(k),ls(last),l,mid,w,x);
        else Change(rs(k),rs(last),mid+1,r,w,x);
    }
    inline void Update(int &k,int last,int l,int r,int w){
        k=NewNode();
        p[k]=p[last];
        if(l==r){MinDis[k]=MinDis[last];fa[k]=fa[last];Dep[k]=Dep[last]+1;return;}
        int mid=(l+r)>>1;
        if(w<=mid) Update(ls(k),ls(last),l,mid,w);
        else Update(rs(k),rs(last),mid+1,r,w);
    }
    inline void Update2(int &k,int last,int l,int r,int w,int x){
        k=NewNode();
        p[k]=p[last];
        if(l==r){MinDis[k]=x;fa[k]=fa[last];Dep[k]=Dep[last];return;}
        int mid=(l+r)>>1;
        if(w<=mid) Update2(ls(k),ls(last),l,mid,w,x);
        else Update2(rs(k),rs(last),mid+1,r,w,x);
    }
    inline void Merge(int &k,int last,int a,int b){
        int faa=Find(last,a),fab=Find(last,b);
        if(fa[faa]==fa[fab]) return;
        Change(k,last,1,n,fa[faa],fa[fab]);
        if(Dep[faa]==Dep[fab]) Update(k,k,1,n,fa[fab]);
        if(MinDis[faa]<MinDis[fab]) Update2(k,k,1,n,fa[fab],MinDis[faa]);
    }
}dsu;

int t;

inline void Init(){
    read(n);read(m);
    for(int i=1;i<=m;i++){
        int from,to,w,h;read(from);read(to);read(w);read(h);
        Add(from,to,w,h);Add(to,from,w,h);
    }
}
//over

struct node{
    int id,val;
    inline node(){}
    inline node(int id,int val) : id(id),val(val) {}
    inline bool operator < (const node &b)const{return val>b.val;}
};
priority_queue<node> q;

inline void Dij(int s){
    // printf("enter\n");
    memset(d,INF,sizeof(d));
    q.push(node(s,0));d[s]=0;
    while(q.size()){
        node top=q.top();q.pop();
        if(vis[top.id]) continue;
        vis[top.id]=1;
        for(int x=head[top.id];x;x=li[x].next){
            int to=li[x].to,w=li[x].w;
            if(d[to]<=d[top.id]+w) continue;
            d[to]=d[top.id]+w;
            q.push(node(to,d[to]));
        }
    }
    // for(int i=1;i<=n;i++) printf("d[%d]=%d\n",i,d[i]);
}
//over

inline void Solve(){
    // printf("enter\n");
    dsu.Build(Root[0],1,n);
    // printf("tot=%d\n",tot);
    sort(li+1,li+tail+1);
    for(int i=1,j=1;i<=tail;i=j){
        rtt++;int last=Root[rtt-1];Root[rtt]=Root[rtt-1];
        while(li[j].High==li[i].High&&j<=tail){
            dsu.Merge(Root[rtt],last,li[j].from,li[j].to);
            last=Root[rtt];j++;
        }
        Hi[rtt]=li[i].High;
    }
    // printf("rtt=%d\n",rtt);
    // for(int i=1;i<=rtt;i++) printf("Hi[%d]=%d\n",i,Hi[i]);
    // for(int i=1;i<=rtt;i++) printf("Root[%d]=%d\n",i,Root[i]);
    // for(int i=1;i<=tot;i++){
    //     if(p[i].ls) printf("%d %d\n",i,p[i].ls);
    //     if(p[i].rs) printf("%d %d\n",i,p[i].rs);
    // }
    // for(int i=1;i<=tot;i++){
    //     printf("fa[%d]=%d\n",i,fa[i]);
    //     printf("MinDis[%d]=%d\n",i,MinDis[i]);
    // }
}

inline int Binary(int High){
    int l=1,r=rtt,ans=0;
    while(l<=r){
        int mid=(l+r)>>1;
        if(Hi[mid]>High){
            ans=l;l=mid+1;
        }
        else r=mid-1;
    }
    return ans;
}

inline void Clear(){
    tail=0;for(int i=1;i<=n;i++) head[i]=0;
    for(int i=1;i<=tot;i++){fa[i]=Dep[i]=0;MinDis[i]=INF;}
    tot=0;
    for(int i=1;i<=n;i++) Root[i]=0;rtt=tail=0;
    Ans=0;for(int i=1;i<=n;i++) vis[i]=0;
    for(int i=1;i<=n;i++) Hi[i]=0;
}

signed main(){
    // freopen("my.in","r",stdin);
    // freopen("my.out","w",stdout);
    read(t);
    memset(MinDis,INF,sizeof(MinDis));
    while(t--){
        Init();Dij(1);Solve();
        read(Q);read(K);read(S);
        for(int i=1;i<=Q;i++){
            int V,P;read(V);read(P);
            V=(V+K*Ans-1)%n+1;
            P=(P+K*Ans)%(S+1);
            // printf("P=%d\n",P);
            int rt=Binary(P);
            // printf("rt=%d\n",rt);
            int now=dsu.Find(Root[rt],V);
            // printf("V=%d\n",V);
            Ans=MinDis[now];
            printf("%lld\n",Ans);
        }
        Clear();
    }
    return 0;
}
2021/10/30 15:27
加载中...