[最短路 主席树 Hash] 51Nod 算法马拉松26 E Travel

来源:互联网 发布:汉诺塔递归算法java 编辑:程序博客网 时间:2024/06/04 00:51

跟这个题一毛一样,那个题还高明一点,还会进位

#include<cstdio>#include<cstdlib>#include<algorithm>#include<queue>#include<map>using namespace std;typedef unsigned int uint;typedef unsigned long long ull;inline char nc(){  static char buf[100000],*p1=buf,*p2=buf;  return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline void read(int &x){  char c=nc(),b=1;  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int N=100205;const int M=10000005;const int P1=233333,P2=255555;uint p1[N+5],p2[N+5];int ls[M],rs[M]; uint H[M];int ncnt,null;inline void Pre(){  p1[0]=p2[0]=1;  for (int i=1;i<=N;i++) p1[i]=p1[i-1]*P1,p2[i]=p2[i-1]*P2;}inline void upd(int x,int l,int r){  int mid=(l+r)>>1;  H[x]=H[ls[x]]+H[rs[x]]*p1[mid-l+1];}int n,m;inline void Build(int &x,int l,int r){  x=++ncnt;  if (l==r){    H[x]=N; return;  }  int mid=(l+r)>>1;  Build(ls[x],l,mid); upd(x,l,r);}inline void Add(int &x,int y,int l,int r,int t){  x=++ncnt; ls[x]=ls[y],rs[x]=rs[y];  if (l==r){    H[x]=H[y]+1;    return;  }  int mid=(l+r)>>1;   if (t<=mid) Add(ls[x],ls[y],l,mid,t);  else Add(rs[x],rs[y],mid+1,r,t);  upd(x,l,r);}inline bool Cmp(int x,int y,int l,int r){  if (l==r) return H[x]<H[y];  int mid=(l+r)>>1;  if (H[ls[x]]==H[ls[y]])    return Cmp(rs[x],rs[y],mid+1,r);  else    return Cmp(ls[x],ls[y],l,mid);}struct edge{  int u,v,next;}G[1000005];int head[N],inum;inline void add(int u,int v,int p){  G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;}#define V G[p].vint dis[N];int back[N],val[N],a[N];int ans[N];inline void Print(int x,int l,int r){  if (l==r){    ans[l]=H[x]; return;  }  int mid=(l+r)>>1;  Print(ls[x],l,mid); Print(rs[x],mid+1,r);}struct abcd{  int u,rt;  abcd(int u=0,int rt=0):u(u),rt(rt) { }  bool operator < (const abcd &B) const{    return Cmp(B.rt,rt,1,n);  }};priority_queue<abcd> Q;inline void Dij(){  Build(null,1,n);  for (int i=2;i<=n;i++) dis[i]=null;  Add(dis[1],0,1,n,val[1]);  Q.push(abcd(1,dis[1]));  while (!Q.empty()){    abcd t=Q.top(); Q.pop();    int u=t.u,d=t.rt;    if (d!=dis[u]) continue;    for (int p=head[u];p;p=G[p].next){      int t; int tmp=ncnt;      Add(t,dis[u],1,n,val[V]);      if (Cmp(t,dis[V],1,n)){    dis[V]=t;    Q.push(abcd(V,dis[V]));      }else    ncnt=tmp;    }  }}int main(){  int x,y;  freopen("t.in","r",stdin);  freopen("t.out","w",stdout);  read(n); read(m); Pre();  for (int i=1;i<=n;i++) read(a[i]),back[a[i]]=i;  for (int i=1;i<=n;i++) read(val[i]),val[i]=back[val[i]];  for (int i=1;i<=m;i++) read(x),read(y),add(x,y,++inum),add(y,x,++inum);  Dij();  Print(dis[n],1,n);  for (int i=1;i<=n;i++)    for (int j=1;j<=ans[i];j++)      printf("%d ",a[i]);  return 0;}
原创粉丝点击