mx 可持久化并查集求调/kel
查看原帖
mx 可持久化并查集求调/kel
610557
shinzanmonoszm 妹妹楼主2023/7/20 00:30
#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<limits>
#include<queue>
using ll=long long;
using piit=std::pair<ll,int>;
const int sz=2e5+10;
const ll inf=std::numeric_limits<ll>::max()/2;
struct edge{
    int u,v,c;
    bool operator<(const edge &a)const{
        return c>a.c;
    }
}g[sz<<1];
int carr[sz];
std::vector<piit>graph[sz];
ll dis[sz];
bool vis[sz];
std::priority_queue<piit,std::vector<piit>,std::greater<piit>>pq;
void dijkstra(int s){
    dis[s]=0,pq.push(std::make_pair(0,s));
    while(!pq.empty()){
        int u=pq.top().second;
        pq.pop();
        if(vis[u])continue;
        vis[u]=true;
        for(auto p:graph[u]){
            int v=p.second;
            if(dis[v]>dis[u]+p.first){
                dis[v]=dis[u]+p.first;
                pq.push(std::make_pair(dis[v],v));
            }
        }
    }
}
template<class __Tp>
struct Array{
    struct node{
        int lson,rson;
        __Tp val;
    }tree[sz<<7];
    int num=0;
    void build(int &p,int ln,int rn,__Tp arr[]){
        p=++num;
        if(ln==rn)return tree[p].val=arr[ln],void();
        int mid=ln+rn>>1;
        build(tree[p].lson,ln,mid,arr);
        build(tree[p].rson,mid+1,rn,arr);
    }
    void modify(int &p,int srt,int ln,int rn,int pos,__Tp val){
        p=++num,tree[p]=tree[srt];
        if(ln==rn)return tree[p].val=val,void();
        int mid=ln+rn>>1;
        if(pos<=mid)modify(tree[p].lson,tree[srt].lson,ln,mid,pos,val);
        else modify(tree[p].rson,tree[srt].rson,mid+1,rn,pos,val);
    }
    void add(int &p,int srt,int ln,int rn,int pos,__Tp val){
        p=++num,tree[p]=tree[srt];
        if(ln==rn)return tree[p].val+=val,void();
        int mid=ln+rn>>1;
        if(pos<=mid)add(tree[p].lson,tree[srt].lson,ln,mid,pos,val);
        else add(tree[p].rson,tree[srt].rson,mid+1,rn,pos,val);
    }
    __Tp query(int p,int ln,int rn,int pos){
        if(ln==rn)return tree[p].val;
        int mid=ln+rn>>1;
        if(pos<=mid)return query(tree[p].lson,ln,mid,pos);
        return query(tree[p].rson,mid+1,rn,pos);
    }
};
int rtf[sz],rts[sz],rtm[sz],arr[sz],n,m,q,k,s,f;
struct UFS{
    Array<int>fa,ssz;
    Array<ll>min;
    void clear(int n){
        std::fill(fa.tree+1,fa.tree+fa.num+1,Array<int>::node{0,0,0});
        std::fill(ssz.tree+1,ssz.tree+ssz.num+1,Array<int>::node{0,0,0});
        std::fill(min.tree+1,min.tree+min.num+1,Array<ll>::node{0,0,0});
        fa.num=ssz.num=min.num=0;
        std::iota(arr+1,arr+n+1,1);
        fa.build(rtf[f],1,n,arr);
        std::fill(arr+1,arr+n+1,1);
        ssz.build(rts[f],1,n,arr);
        std::fill(dis+1,dis+n+1,inf);
        std::fill(vis+1,vis+n+1,0);
        dijkstra(1);
        min.build(rtm[f],1,n,dis);
    }
    int find(int vrt,int u){
        int fu=fa.query(rtf[vrt],1,n,u);
        if(fu==u)return u;
        return find(vrt,fu);
    }
    void merge(int vrt,int u,int v){
        int fu=find(vrt,u),fv=find(vrt,v);
        if(fu==fv)return;
        if(ssz.query(rts[vrt],1,n,fu)>ssz.query(rts[vrt],1,n,fv))std::swap(fu,fv);
        fa.modify(rtf[vrt],rtf[vrt],1,n,fu,fv);
        ssz.add(rts[vrt],rts[vrt],1,n,fv,ssz.query(rts[vrt],1,n,fu));
        ll mu=min.query(rtm[vrt],1,n,fu),mv=min.query(rtm[vrt],1,n,fv);
        min.modify(rtm[vrt],rtm[vrt],1,n,fv,std::min(mu,mv));
    }
    ll qmin(int vrt,int u){
        int fu=find(vrt,u);
        return min.query(rtm[vrt],1,n,fu);
    }
}ufs;
int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int t;
    std::cin>>t;
    while(t--){
        std::cin>>n>>m;
        for(int i=1;i<=n;i++)graph[i].clear();
        for(int i=1;i<=m;i++){
            int u,v,l,a;
            std::cin>>u>>v>>l>>a;
            graph[u].push_back(std::make_pair(l,v));
            graph[v].push_back(std::make_pair(l,u));
            g[i]=edge{u,v,a},carr[i]=a;
        }
        std::sort(carr+1,carr+m+1);
        f=std::unique(carr+1,carr+m+1)-carr;
        for(int i=1;i<=m;i++)
            g[i].c=std::lower_bound(carr+1,carr+f,g[i].c)-carr;
        ufs.clear(n);
        std::sort(g+1,g+m+1),g[0].c=f;
        for(int i=1,j=1;i<=m;i=j){
            rtf[g[i].c]=rtf[g[i-1].c];
            rts[g[i].c]=rts[g[i-1].c];
            rtm[g[i].c]=rtm[g[i-1].c];
            while(j<=m&&g[j].c==g[i].c)
                ufs.merge(g[j].c,g[j].u,g[j].v),j++;
        }
        std::cin>>q>>k>>s,s++;
        ll lans=0;
        while(q--){
            int v,p;
            std::cin>>v>>p;
            v=(1ll*v+k*lans-1)%n+1,p=(1ll*p+k*lans)%s;
            p=std::upper_bound(carr+1,carr+f,p)-carr;
            lans=ufs.qmin(p,v);
            std::cout<<lans<<"\n";
        }
    }
    return 0;
}

2023/7/20 00:30
加载中...