• 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;
    }
  • 相关阅读:
    Berry Jam(前缀后>差值,贪心)
    Privatization of Roads in Treeland (贪心+染色)
    主席树
    C 语言是一门抽象的、面向过程的语言,C 语言广泛应用于底层开发
    限流中间件AspNetCoreRateLimit
    远程调试 Visual Studio2022
    高并发下秒杀
    设计模式的分类和六大原则
    MySQL的锁机制
    代码是怎么运行
  • 原文地址:https://www.cnblogs.com/cytus/p/9524581.html
Copyright © 2020-2023  润新知