zoukankan      html  css  js  c++  java
  • UOJ 393 【NOI2018】归程——可持久化并查集

    题目:http://uoj.ac/problem/393

    题解:https://www.cnblogs.com/HocRiser/p/9368067.html

    但过不了 UOJ 的 hack 数据。不知道是哪里出错。之后再管吧。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #define mkp make_pair
    #define pb push_back
    using namespace std;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    const int N=2e5+5,M=4e5+5,INF=2e9+5;
    int n,m,hd[N],xnt,to[M<<1],nxt[M<<1],w[M<<1],dis[N];
    int fa[N],ht[N],mn[N],dep[N]; bool vis[N];
    struct Ed{
      int x,y,h;
      Ed(int x=0,int y=0,int h=0):x(x),y(y),h(h) {}
      bool operator< (const Ed &b)const
      {return h>b.h;}
    }ed[M];
    struct Node{
      int h,v;
      Node(int h=0,int v=0):h(h),v(v) {}
      bool operator< (const Node &b)const
      {return h>b.h;}
    };
    priority_queue<pair<int,int> > q;
    vector<Node> Mn[N];
    vector<Node>::iterator it;
    void add(int x,int y,int z){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;w[xnt]=z;}
    void dj()
    {
      memset(vis,0,sizeof vis);
      for(int i=2;i<=n;i++)dis[i]=INF;
      q.push(mkp(0,1));
      while(q.size())
        {
          int k=q.top().second; q.pop();
          if(vis[k])continue; vis[k]=1;
          for(int i=hd[k],v;i;i=nxt[i])
        if(dis[v=to[i]]>dis[k]+w[i])
          {
            dis[v]=dis[k]+w[i];
            q.push(mkp(-dis[v],v));
          }
        }
    }
    int fnd(int u,int p)
    {
      while(fa[u]!=u&&ht[u]>p)u=fa[u];
      return u;
    }
    int fnd2(int u,int p)
    {
      it=--lower_bound(Mn[u].begin(),Mn[u].end(),Node(p,0));
      return (*it).v;
    }
    int main()
    {
      int T=rdn();
      while(T--)
        {
          n=rdn();m=rdn();
          xnt=0; memset(hd,0,sizeof hd);
          for(int i=1,u,v,l,h;i<=m;i++)
        {
          u=rdn();v=rdn();l=rdn();h=rdn();
          add(u,v,l);add(v,u,l);
          ed[i]=Ed(u,v,h);
        }
          dj(); sort(ed+1,ed+m+1);
          for(int i=1;i<=n;i++)
        {
          Mn[i].clear();
          Mn[i].pb(Node(INF,mn[i]=dis[i]));
          fa[i]=i; dep[i]=1;
        }
          for(int i=1;i<=m;i++)
        {
          int u=fnd(ed[i].x,0), v=fnd(ed[i].y,0);
          if(u==v)continue;
          if(dep[u]>dep[v])swap(u,v);
          if(dep[u]==dep[v])dep[v]++;
          fa[u]=v; ht[u]=ed[i].h;
          if(mn[u]<mn[v])
            Mn[v].pb(Node(ed[i].h,mn[v]=mn[u]));
        }
          int Q=rdn(),K=rdn(),S=rdn()+1,ans=0;
          for(int i=1,u,p;i<=Q;i++)
        {
          u=(rdn()+(K?ans:0)-1)%n+1;
          p=(rdn()+(K?ans:0))%S;
          u=fnd(u,p); ans=fnd2(u,p);
          printf("%d
    ",ans);
        }
        }
      return 0;
    }
    View Code

     还写了可持久化并查集的。在 UOJ 上TLE最后两个点,在 LOJ 上能过。

    注意每次 tot=0 。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define mkp make_pair
    using namespace std;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    int Mn(int a,int b){return a<b?a:b;}
    const int N=2e5+5,M=4e5+5,K=36*M,INF=2147483647;
    int n,m,hd[N],xnt,to[M<<1],nxt[M<<1],w[M<<1],dis[N];
    int tp[M],rt[M],ht[M]; bool vis[N];
    int tot,ls[K],rs[K],vl[K],dep[K],mn[K];
    struct Ed{
      int x,y,h;
      Ed(int x=0,int y=0,int h=0):x(x),y(y),h(h) {}
      bool operator< (const Ed &b)const
      {return h>b.h;}
    }ed[M];
    priority_queue<pair<int,int> > q;
    void add(int x,int y,int z)
    {to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;w[xnt]=z;}
    void dj()
    {
      memset(vis,0,sizeof vis);
      for(int i=2;i<=n;i++)dis[i]=INF;
      q.push(mkp(0,1));
      while(q.size())
        {
          int k=q.top().second; q.pop();
          if(vis[k])continue; vis[k]=1;
          for(int i=hd[k],v;i;i=nxt[i])
        if(dis[v=to[i]]>dis[k]+w[i])
          dis[v]=dis[k]+w[i], q.push(mkp(-dis[v],v));
        }
    }
    void build(int l,int r,int& cr)
    {
      cr=++tot;
      if(l==r){vl[cr]=l;dep[cr]=1;mn[cr]=dis[l];return;}
      int mid=l+r>>1;
      build(l,mid,ls[cr]); build(mid+1,r,rs[cr]);
    }
    void ins(int l,int r,int& cr,int pr,int p)
    {
      cr=++tot;ls[cr]=ls[pr];rs[cr]=rs[pr];
      if(l==r)
        {
          vl[cr]=vl[pr];dep[cr]=dep[pr];
          mn[cr]=mn[pr];return;
        }
      int mid=l+r>>1;
      if(p<=mid)ins(l,mid,ls[cr],ls[pr],p);
      else ins(mid+1,r,rs[cr],rs[pr],p);
    }
    int qry(int l,int r,int cr,int p)
    {
      if(l==r)return cr; int mid=l+r>>1;
      if(p<=mid)return qry(l,mid,ls[cr],p);
      else return qry(mid+1,r,rs[cr],p);
    }
    int fnd(int nw,int a)
    {
      int fa=qry(1,n,nw,a);
      if(vl[fa]==a)return fa;
      return fnd(nw,vl[fa]);
    }
    int fnd2(int p)
    {
      int l=0,r=m,ret=0;//l=0
      while(l<=r)
        {
          int mid=l+r>>1;
          if(ht[mid]>p)ret=mid,l=mid+1;
          else r=mid-1;
        }
      return ret;
    }
    int main()
    {
      int T=rdn();
      while(T--)
        {
          n=rdn();m=rdn();
          xnt=0; memset(hd,0,sizeof hd);
          for(int i=1,u,v,l,a;i<=m;i++)
        {
          u=rdn();v=rdn();l=rdn();a=rdn();
          add(u,v,l); add(v,u,l);
          ed[i]=Ed(u,v,a); tp[i]=a;
        }
          dj(); int Q=rdn(),K=rdn(),S=rdn();
          tot=0;//////
          sort(ed+1,ed+m+1); build(1,n,rt[0]);
          /*
          for(int i=1,u,v;i<=m;i++)
        {
          rt[i]=rt[i-1];
          u=fnd(rt[i],ed[i].x); v=fnd(rt[i],ed[i].y);
          if(vl[u]==vl[v])continue;
          if(dep[u]>dep[v])swap(u,v);
          ins(1,n,rt[i],rt[i],vl[u]);u=tot;
          ins(1,n,rt[i],rt[i],vl[v]);v=tot;
          vl[u]=vl[v]; mn[v]=Mn(mn[v],mn[u]);
          if(dep[u]==dep[v])dep[v]++;
        }
          */
          int lm=m; m=1;
          for(int i=1,u,v;i<=lm;m++)
        {
          rt[m]=rt[m-1]; ht[m]=ed[i].h;
          while(i<=lm&&ed[i].h==ht[m])
            {
              u=fnd(rt[m],ed[i].x); v=fnd(rt[m],ed[i].y);
              i++; if(vl[u]==vl[v])continue;
              if(dep[u]>dep[v])swap(u,v);
              ins(1,n,rt[m],rt[m],vl[u]);u=tot;
              ins(1,n,rt[m],rt[m],vl[v]);v=tot;
              vl[u]=vl[v]; mn[v]=Mn(mn[v],mn[u]);
              if(dep[u]==dep[v])dep[v]++;
            }
        }
          int ans=0; S++; m--; ht[0]=INF;//
          for(int i=1,v,p;i<=Q;i++)
        {
          v=(rdn()+(K?ans:0)-1)%n+1;
          p=(rdn()+(K?ans:0))%S; p=fnd2(p);
          //p=lower_bound(ed+1,ed+m+1,Ed(0,0,p))-ed-1;
          v=fnd(rt[p],v); ans=mn[v];
          printf("%d
    ",ans);
        }
        }
      return 0;
    }
    View Code
  • 相关阅读:
    天融信防火墙抓包
    windows2019jihuo
    CentOS多路径软件配置(光纤连接存储)
    listener.ora,tnsnames.ora中一个空格的威力
    excel 金额自动转中文大写
    js的点滴
    写ppt的助手
    珠峰-6-koa-express
    珠峰-6-http和http-server原理
    珠峰-6-node
  • 原文地址:https://www.cnblogs.com/Narh/p/10385172.html
Copyright © 2011-2022 走看看