Evanyou Blog 彩带

  题目传送门

归程

格式难调,题面就不放了。


  分析:

  之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做。

  但是之前做可持久化并查集的时候感觉掌握的并不熟,还是需要参照别人的题解,不过至少现在对可持久化的理解更深了一步,而且终于这题给调对了。

  Code:

//It is made by HolseLee on 23rd Aug 2018
//Luogu.org 4768
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define Min(a,b) (a)<(b)?(a):(b)
#define Max(a,b) (a)>(b)?(a):(b)
using namespace std;

const int N=2e5+7,M=8e5+7,S=2e7+1;
typedef unsigned int ui;
ui T,n,m,Q,K,s,lastans,L,cnt;
ui head[N],nxt[M],to[M],d[M],a[M],b[M],dis[N];
ui rt[M],lc[S],rc[S],dep[S],fa[S],mn[S];
bool vis[N];
struct Node{
    ui id,val;
    bool operator < (const Node x) const {
        return val>x.val;
    }
    Node(ui x=0,ui y=0){
        id=x,val=y;
    }
};
struct Edge{
    ui u,v,h;
    bool operator < (const Edge x) const {
        return h<x.h;
    }
    Edge(ui x=0,ui y=0,ui z=0){
        u=x,v=y,h=z;
    }
}e[M];
priority_queue<Node> t; 

inline ui read()
{
    char ch=getchar();ui num=0;
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch>='0'&&ch<='9'){
        num=(num<<1)+(num<<3)+(ch^48);ch=getchar();
    }
    return num;
}

void build(ui &root,ui l,ui r)
{
    root=++cnt;
    if(l==r){mn[root]=dis[fa[root]=l];return;}
    ui mid=(l+r)>>1;
    build(lc[root],l,mid);
    build(rc[root],mid+1,r);
}

ui ins(ui *root,ui las,ui tag)
{
    ui l=1,r=n,mid;
    while(l!=r){
        *root=++cnt,mid=(l+r)>>1;
        if(tag<=mid)r=mid,rc[*root]=rc[las],root=lc+*root,las=lc[las];
        else l=mid+1,lc[*root]=lc[las],root=rc+*root,las=rc[las];
    }
    return *root=++cnt;
}

ui find(ui root,ui tag)
{
    ui now,l,r,mid;
    while(1){
        now=root,l=1,r=n;
        while(l!=r){
            mid=(l+r)>>1;
            if(tag<=mid)r=mid,now=lc[now];
            else l=mid+1,now=rc[now];
        }
        if(tag==fa[now])break;
        tag=fa[now];
    }
    return now;
}

int main()
{
    T=read();
    ui i,j;
    while(T--){
        n=read();m=read();
        ui x,y,w,cnte=0;cnt=0;
        for(i=1;i<=m;++i){
            x=read();y=read();
            to[++cnte]=y,nxt[cnte]=head[x],head[x]=cnte;
            to[++cnte]=x,nxt[cnte]=head[y],head[y]=cnte;
            d[cnte]=d[cnte-1]=read();
            e[i]=Edge(x,y,a[cnte]=a[cnte-1]=read());
        }
        memset(dis,-1,(n+1)<<2);
        dis[1]=0;t.push(Node(1,0));
        while(!t.empty()){
            Node now=t.top();t.pop();
            if(vis[x=now.id])continue;
            vis[x]=true;
            for(i=head[x];i;i=nxt[i]){
                y=to[i];
                if(dis[y]>dis[x]+d[i])
                t.push(Node(y,dis[y]=dis[x]+d[i]));
            }
        }
        Q=read(),K=read(),s=read();lastans=0;
        sort(e+1,e+m+1);
        for(i=1;i<=m;++i)b[i]=e[i].h;
        b[m+1]=s+1;
        L=unique(b+1,b+m+2)-b-1;
        build(rt[L],1,n);
        for(i=L-1,j=m;i;--i){
            rt[i]=rt[i+1];
            for(;j&&e[j].h==b[i];--j){
                if((x=find(rt[i],e[j].u))==(y=find(rt[i],e[j].v)))continue;
                if(dep[x]>dep[y])swap(x,y);
                fa[ins(&rt[i],rt[i],fa[x])]=fa[y];
                w=ins(&rt[i],rt[i],fa[y]);
                fa[w]=fa[y];mn[w]=Min(mn[x],mn[y]);
                dep[w]=dep[y]+(dep[y]==dep[x]);
            }
        }
        for(;Q;--Q){
            x=(read()+K*lastans-1)%n+1;
            y=(read()+K*lastans)%(s+1);
            printf("%u
",lastans=mn[find(rt[upper_bound(b+1,b+L+1,y)-b],x)]);
        }
        memset(vis,0,n+1);
        memset(head,0,(n+1)<<2);
        memset(rt,0,(L+1)<<2);
        memset(lc,0,(cnt+1)<<2);
        memset(rc,0,(cnt+1)<<2);
        memset(fa,0,(cnt+1)<<2);
        memset(mn,0,(cnt+1)<<2);
        memset(dep,0,(cnt+1)<<2);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cytus/p/9524581.html