[最短路 && 主席树维护HASH]Codeforces 464E. The Classic Problem

来源:互联网 发布:淘宝助理 电子面单 编辑:程序博客网 时间:2024/06/07 07:17

传送门
老套路
跟51nod1863一样。
就是多了进位

#include <cstdio>#include <iostream>#include <algorithm>#include <set>#include <cstring>#include <string>#include <vector>#include <queue>#include <assert.h>#define fi first#define se secondusing namespace std;typedef unsigned int ll;typedef pair<int,int> ii;const int N=100105,P1=1e9+7,P2=1e9+9,MAX=100100;const ll base=100003;bool bg;int n,m,cnt,cnt0,g,rt[N*280],ls[N*280],rs[N*280],tag[N*280],G[N],len[N];ll pw[N],v[N*280],p[N];struct edge{  int t,nx,w;}E[N<<1];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 rea(int &x){  char c=nc(); x=0;  for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());}inline void set1(int &g,int l,int r){  int k=g; g=++cnt; ls[g]=ls[k]; rs[g]=rs[k]; tag[g]=tag[k]; v[g]=v[k]; v[g]=p[r-l]; tag[g]=1;}inline void set0(int &g,int l,int r){  int k=g; g=++cnt; ls[g]=ls[k]; rs[g]=rs[k]; tag[g]=tag[k]; v[g]=v[k];  v[g]=0; tag[g]=0;}inline void Push(int &g,int L,int R){  if(~tag[g]){    int k=g; g=++cnt; ls[g]=ls[k]; rs[g]=rs[k]; tag[g]=tag[k]; v[g]=v[k];    int mid=L+R>>1;    if(tag[g])      set1(ls[g],L,mid),set1(rs[g],mid+1,R);    else      set0(ls[g],L,mid),set0(rs[g],mid+1,R);    tag[g]=-1;  }}inline bool cmp(int &a,int &b,int l,int r){  if(v[a]==0 && v[b]) return true;  if(v[a] && v[b]==0) return false;  if(v[a]==v[b]) return false;  if(l==r) return v[a]<v[b];  if(tag[a]!=-1 || tag[b]!=-1)    int sss=0;  assert(tag[a]==-1 && tag[b]==-1);  int mid=l+r>>1;  if(v[ls[a]]==v[ls[b]])    return cmp(rs[a],rs[b],mid+1,r);  else    return cmp(ls[a],ls[b],l,mid);}struct U{  int x,y;  friend bool operator ==(U a,U b){    return v[a.y]==v[b.y];  }  friend bool operator <(U a,U b){    if(v[a.y]==v[b.y]) return false;    return !cmp(a.y,b.y,1,MAX);  }};priority_queue<U> Q;int Find(int &g,int l,int r,int L,int R){  if(v[g]==0) return r;  if(v[g]==p[R-L]) return -1;  if(!g) return r;  if(L==R) return v[g]?-1:L;  int mid=L+R>>1;   if(l==L && r==R){    if(v[rs[g]]!=p[R-mid-1]) return Find(rs[g],mid+1,r,mid+1,R);    return Find(ls[g],l,mid,L,mid);  }  if(r<=mid) return Find(ls[g],l,r,L,mid);  else if(l>mid) return Find(rs[g],l,r,mid+1,R);  int ret=Find(rs[g],mid+1,r,mid+1,R);  if(~ret) return ret;  return Find(ls[g],l,mid,L,mid);}inline void Up(int g,int l){  v[g]=v[ls[g]]*pw[l]+v[rs[g]];}void Cover(int &g,int l,int r,int L,int R){  int k=g; g=++cnt; ls[g]=ls[k]; rs[g]=rs[k]; tag[g]=tag[k]; v[g]=v[k];  if(l==L && r==R) return set0(g,L,R);  int mid=L+R>>1; Push(g,L,R);  if(r<=mid) Cover(ls[g],l,r,L,mid);  else if(l>mid) Cover(rs[g],l,r,mid+1,R);  else Cover(ls[g],l,mid,L,mid),Cover(rs[g],mid+1,r,mid+1,R);  Up(g,R-mid);}void Modify(int &g,int x,int L,int R){  int k=g; g=++cnt; ls[g]=ls[k]; rs[g]=rs[k]; tag[g]=tag[k]; v[g]=v[k];  if(L==R) return set1(g,L,R);  int mid=L+R>>1; Push(g,L,R);  if(x<=mid) Modify(ls[g],x,L,mid);else Modify(rs[g],x,mid+1,R);  Up(g,R-mid);}int ans,ss,tt,frm[N];void dfs(int &g,int l,int r){  if(l==r){    ans=(2LL*ans+v[g])%P1;    return ;  }  int mid=l+r>>1; Push(g,l,r);  dfs(ls[g],l,mid); dfs(rs[g],mid+1,r);}int prnt[N],pnt;inline void add(int x,int y,int z){  E[++cnt0].t=y; E[cnt0].nx=G[x]; E[cnt0].w=z; G[x]=cnt0;  E[++cnt0].t=x; E[cnt0].nx=G[y]; E[cnt0].w=z; G[y]=cnt0;}bool ed;int main(){  pw[0]=p[0]=1; for(int i=1;i<=MAX;i++) p[i]=p[i-1]+(pw[i]=pw[i-1]*base);  rea(n); rea(m);  memset(tag,-1,sizeof(tag));  for(int i=1;i<=m;i++){    int x,y,z; rea(x); rea(y); rea(z);    add(x,y,z);  }  int ss,tt; rea(ss); rea(tt);  Cover(rt[ss],1,MAX,1,MAX);  Q.push(U{ss,rt[ss]});  while(!Q.empty()){    int x=Q.top().x,y=Q.top().y; Q.pop();    if(y!=rt[x]) continue;    for(int i=G[x];i;i=E[i].nx){      int u=E[i].t,val=MAX-E[i].w,cur=y,lst=cnt,cg=0;      int pos=Find(cur,1,val,1,MAX);      if(pos+1<=val) Cover(cur,pos+1,val,1,MAX);      Modify(cur,pos,1,MAX); int r=rt[u];      if(!r || cmp(cur,r,1,MAX)){    cg=1; rt[u]=cur; frm[u]=x; Q.push(U{u,rt[u]});      }      if(!cg) cnt=lst;    }  }  if(!rt[tt]) puts("-1");  else{    dfs(rt[tt],1,MAX);    printf("%d\n",ans);    while(tt){      prnt[++pnt]=tt; tt=frm[tt];    }    printf("%d\n",pnt);    for(int i=pnt;i;i--) printf("%d ",prnt[i]);  }  return 0;}
阅读全文
0 0
原创粉丝点击