用主席树维护距离的二进制位
处理进位可以二分第一个为0的地方
比较大小的话可以通过哈希找到第一个不同的地方
复杂度
主席树多开个位置处理进位
写的单哈希被卡了
于是写了个双哈希
#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ob==ib)?EOF:*ib++;
}
#define gc getchar
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cs const
#define ull unsigned long long
const int mod=1e9+7,g=3;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline void Add(int &a,int b){a=add(a,b);}
inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
inline void Dec(int &a,int b){a=dec(a,b);}
inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
inline void Mul(int &a,int b){a=mul(a,b);}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,a=mul(a,a))(b&1)?(res=mul(res,a)):0;return res;}
inline void chemx(int &a,int b){a<b?a=b:0;}
inline void chemn(int &a,int b){a>b?a=b:0;}
cs int N=100505;
cs ull mod1=1004535809;
cs ull mod2=2281701377;
ull bas1,bas2;
ull pw1[N],pw2[N];
int mx,bin[N];
namespace Pt{
cs int M=N*200;
ull has1[M],has2[M];
int lc[M],rc[M],siz[M],tot;
#define mid ((l+r)>>1)
inline void pushup(int u,int l,int r){
siz[u]=siz[lc[u]]+siz[rc[u]];
has1[u]=(has1[lc[u]]*pw1[mid-l+1]%mod1+has1[rc[u]])%mod1;
has2[u]=(has2[lc[u]]*pw2[mid-l+1]%mod2+has2[rc[u]])%mod2;
}
inline void insert(int r1,int &u,int l,int r,int p){
u=++tot;
siz[u]=siz[r1]+1,lc[u]=lc[r1],rc[u]=rc[r1];
if(l==r){has1[u]=l,has2[u]=l;return;}
if(p<=mid)insert(lc[r1],lc[u],l,mid,p);
else insert(rc[r1],rc[u],mid+1,r,p);
pushup(u,l,r);
}
inline int find(int r1,int r2,int l,int r){
if(l==r){return siz[r1]>=siz[r2];}
if(has1[rc[r1]]!=has1[rc[r2]]||has2[rc[r1]]!=has2[rc[r2]])return find(rc[r1],rc[r2],mid+1,r);
return find(lc[r1],lc[r2],l,mid);
}
inline int comp(int a,int b){
int k=find(a,b,0,mx);
if(k==1)return true;
else return false;
}
inline void delet(int r1,int &u,int l,int r,int st,int des){
if(!u)return;
if(st<=l&&r<=des){u=0;return;}
u=++tot;lc[u]=lc[r1],rc[u]=rc[r1],siz[u]=siz[r1];
if(st<=mid)delet(lc[r1],lc[u],l,mid,st,des);
if(mid<des)delet(rc[r1],rc[u],mid+1,r,st,des);
pushup(u,l,r);
}
inline int query(int u,int l,int r,int st,int des){
if(!u)return 0;
if(st<=l&&r<=des)return siz[u];
int res=0;
if(st<=mid)res+=query(lc[u],l,mid,st,des);
if(mid<des)res+=query(rc[u],mid+1,r,st,des);
return res;
}
inline int goup(int u,int p){
int k=query(u,0,mx,p,p);
if(!k){insert(u,u,0,mx,p);return u;}
int L=p+1,R=mx,res=mx;
while(L<=R){
int mi=(L+R)>>1 ;
if(query(u,0,mx,p+1,mi)==mi-p)L=mi+1;
else R=mi-1,res=mi;
}
delet(u,u,0,mx,p,res-1);
insert(u,u,0,mx,res);
return u;
}
inline int calc(int u,int l,int r){
if(!u) return 0;
if(l==r)return bin[l];
return add(calc(lc[u],l,mid),calc(rc[u],mid+1,r));
}
}
using namespace Pt;
struct node{
int x,y;
friend inline bool operator <(cs node &a,cs node &b){
return comp(a.x,b.x);
}
};
priority_queue<node> q;
int n,m,str,des,dis[N],pre[N],vis[N];
int adj[N],nxt[N<<1],to[N<<1],val[N<<1],cnt;
inline void add(int u,int v,int w){
nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,val[cnt]=w;
}
inline void dijkstra(){
dis[str]=++tot,q.push(node{dis[str],str});
while(!q.empty()){
int u=q.top().y;q.pop();
if(vis[u])continue;
vis[u]=1;
for(int e=adj[u];e;e=nxt[e]){
int v=to[e],k=goup(dis[u],val[e]);
if(!dis[v]||comp(dis[v],k)){
dis[v]=k,pre[v]=u;
q.push(node{dis[v],v});
}
}
}
}
int ans[N*20],top;
int main(){
srand(time(NULL));
bas1=rand(),bas2=rand();
n=read(),m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
add(u,v,w),add(v,u,w);
chemx(mx,w);
}
mx+=100;
pw1[0]=pw2[0]=bin[0]=1;
for(int i=1;i<N;i++)pw1[i]=pw1[i-1]*bas1%mod1,pw2[i]=pw2[i-1]*bas2%mod2,bin[i]=mul(bin[i-1],2);
str=read(),des=read();
dijkstra();
if(!dis[des]){return puts("-1"),0;}
cout<<calc(dis[des],0,mx)<<'
';
ans[top=1]=des;
for(int i=des;i!=str;)i=pre[i],ans[++top]=i;
cout<<top<<'
';
for(int i=top;i;i--)cout<<ans[i]<<" ";
}