「NOI2018」归程

    显然可以持久化并查集。

     (我的写法并不好,因为没有路径压缩,其实可以路径压缩。做到O(Nαlog) 。)

#include<bits/stdc++.h>
#define Mid (l+r>>1)
using namespace std;
#define N 200007
#define M 400007
#define eho(x) for(int i=head[x];i;i=net[i])
#define v fall[i]
#define fi first
#define se second
#define inf (INT_MAX>>1)
#define sight(x) ('0'<=x&&x<='9')
inline void read(int &x){
    static char c;
    for (c=getchar();!sight(c);c=getchar());
    for (x=0;sight(c);c=getchar())x=x*10+c-48;
}
void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('
'); }
inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
priority_queue<pair<int,int> > Q;
int dis[N],head[N],net[M<<1],fall[M<<1],ot,co[M<<1],in[N];
int ls[N*35],rs[N*35],V[N*35],p[N*35],x,tot,n,m,T,last;
inline void add(int x,int y,int Co){
   fall[++ot]=y; net[ot]=head[x]; head[x]=ot; co[ot]=Co;
   fall[++ot]=x; net[ot]=head[y]; head[y]=ot; co[ot]=Co;
}
void spfa(){
    memset(dis,121,sizeof dis);
    dis[1]=0; Q.push(make_pair(0,1));
    while (!Q.empty()){
        pair<int,int> t=Q.top();Q.pop();
        if (-t.fi!=dis[t.se]) continue;
        x=t.se;
        eho(x) if (dis[x]+co[i]<dis[v]){
            dis[v]=dis[x]+co[i];
            Q.push(make_pair(-dis[v],v));
        }
    }
}
void build(int &k,int l,int r){
    if(!k)k=++tot;
    if(l==r){V[k]=l;p[k]=dis[l]; return;}
    build(ls[k],l,Mid);
    build(rs[k],Mid+1,r);
}
void change(int last,int &now,int l,int r,int pos,int to){
    now=++tot;
    if (l==r) {V[now]=to; p[now]=p[last];return;}
    ls[now]=ls[last]; rs[now]=rs[last]; p[now]=p[last]; V[now]=V[last];
    if (pos<=Mid) change(ls[last],ls[now],l,Mid,pos,to);
    else change(rs[last],rs[now],Mid+1,r,pos,to);
}
void Change(int last,int &now,int l,int r,int pos,int to){
    now=++tot;
    if (l==r) {V[now]=V[last];p[now]=to; return;}
    ls[now]=ls[last]; rs[now]=rs[last]; p[now]=p[last]; V[now]=V[last];
    if (pos<=Mid) Change(ls[last],ls[now],l,Mid,pos,to);
    else Change(rs[last],rs[now],Mid+1,r,pos,to);
}
int orz;
void query(int k,int l,int r,int pos){
    if(l==r) {orz=V[k]; return; }
    if(pos<=Mid) query(ls[k],l,Mid,pos);
    else  query(rs[k],Mid+1,r,pos);
}
int Query(int k,int l,int r,int pos){
    if(l==r)return p[k];
    if(pos<=Mid)return Query(ls[k],l,Mid,pos);
    else return Query(rs[k],Mid+1,r,pos);
}
int gf(int k,int x){
    query(k,1,n,x);
    if(x==orz)return x;
    return gf(k,orz);
}
struct edge{
    int x,y,l,a;
    edge(){}
    edge(int _x,int _y,int _l,int _a):x(_x),y(_y),l(_l),a(_a){}
    inline bool operator <(const edge& p)const{
       return a==p.a?l>p.l:a>p.a;
    }
}e[M];int siz[N],fx,fy,rt[M],Pp,Qq,k,s,st,op,it;
void clear() {
    last=0; tot=0; ot=0; x=0;
        memset(head,0,sizeof head);
        memset(ls,0,sizeof ls);
        memset(rs,0,sizeof rs);
        memset(rt,0,sizeof rt);
}
signed main () {
    freopen("return.in","r",stdin);
    freopen("return.out","w",stdout);
    read(T);
    while (T--) {
        clear();
        read(n); read(m);
        for (int i=1;i<=m;i++)
         read(e[i].x),read(e[i].y),
         read(e[i].l),read(e[i].a);
        sort(e+1,e+m+1);
        for (int i=1;i<=m;i++) 
         add(e[i].x,e[i].y,e[i].l);
        spfa();
        build(rt[0],1,n);
        for (int i=1;i<=n;i++) siz[i]=1;
        for (int i=1;i<=m;i++) {
            fx=gf(rt[i-1],e[i].x); 
            fy=gf(rt[i-1],e[i].y);
            if (fx==fy) {rt[i]=rt[i-1]; continue;}
            if (siz[fx]<siz[fy]) swap(fx,fy);
            Pp=Query(rt[i-1],1,n,fx);
            Qq=Query(rt[i-1],1,n,fy);
            change(rt[i-1],rt[i],1,n,fy,fx);
            if (Pp>Qq) Change(rt[i],rt[i],1,n,fx,Qq);
            siz[fx]+=siz[fy];
        }
        read(Qq); read(k); read(s);
        while (Qq--) {
            read(st); read(op);
            st=(st+k*last-1)%n+1;
            op=(op+k*last)%(s+1);
            it=upper_bound(e+1,e+m+1,edge(0,0,inf,op))-e-1;
            Pp=gf(rt[it],st); 
            writeln(last=Query(rt[it],1,n,Pp));
        }
        cerr<<tot<<endl;
    } return 0;
}
原文地址:https://www.cnblogs.com/rrsb/p/9489534.html