论省选前的智商
很奇怪啊Hash会错 而且一样的Hash开的数组不一样大WA的点还不一样
对于这一题 我们可以将加法转换为一段01的转化
然后就可以用线段树表示权值
为了减小空间我们使用可持久化的
有个坑点就是如果用spfa的话会由于修改太多MLE (不要问我是怎么知道的 我才不说我一个早上都在压spfa的内存 最后重打了Dij
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
char c;
inline void read(int &a){a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
struct Node
{
Node *lc,*rc;
bool flag;
int Hash;
int sum;
};
int Pow[140001];
Node *Cache;
int tott=100000000;
const
int Maxt=6000000;
const
int Mod=1e9+7;
int cnt;
inline Node *New(){cnt++;if(tott>=Maxt)tott=0,Cache=new Node[Maxt+1];return Cache+tott++;}
inline void updata(Node *A,int l,int r)
{
A->sum=(A->lc?A->lc->sum:0)+(A->rc?A->rc->sum:0);
A->Hash=((A->lc?A->lc->Hash:0)*1ll*Pow[(0ll+r-(l+r>>1))]+(A->rc?A->rc->Hash:0))%Mod;}
inline void pushdown(Node *a)
{
if(!a->lc)return ;
a->flag=false;
Node *R=New();
*R=*a->lc;
R->flag=1;
R->sum=0;
R->Hash=0;
a->lc=R;
R=New();
*R=*a->rc;
R->flag=1;
R->sum=0;
R->Hash=0;
a->rc=R;
}
bool cmp(Node *a,Node *b,int L,int R)
{
if(a->flag)pushdown(a);
if(b->flag)pushdown(b);
if(L==R)
return !a->sum;
int mid=L+R>>1;
if((a->lc->sum^b->lc->sum)||(a->lc->Hash^b->lc->Hash))
return cmp(a->lc,b->lc,L,mid);
if((a->rc->sum^b->rc->sum)||(a->rc->Hash^b->rc->Hash))
return cmp(a->rc,b->rc,mid+1,R);
return false;
}
inline Node *Addflag(Node *a)
{
Node *A=New();
*A=*a;
A->flag=1;
A->Hash=0;
A->sum=0;
return A;
}
inline Node* Add(Node *a,int l,bool &out,int L,int R)
{
if(a->flag)pushdown(a);
int mid=L+R>>1;
if(L==R&&a->sum)return out=true,Addflag(a);
else if(L==R){Node *A=New();*A=*a;A->Hash=1,A->sum=1,A->flag=false;out=false;return A;}
if(l<=mid)
{Node *A=New();*A=*a;A->lc=Add(a->lc,l,out,L,mid);updata(A,L,R);return A;}
Node *A=New();*A=*a;A->rc=Add(a->rc,l,out,mid+1,R);
if(out)
if(A->lc->sum==mid-L+1)A->lc=Addflag(A->lc);
else
{
bool T=false;
A->lc=Add(A->lc,mid,T,L,mid);
out=false;
}
updata(A,L,R);
return A;
}
queue<int >Q;
bool vis[110001],done[110001];
Node *Dis[110001];
int pre[110001];
const
int Max=110000;
Node *Build(int l,int r)
{
if(l==r){Node *R=New();R->Hash=R->flag=R->sum=0;return R;}
Node *R=New();
R->Hash=R->flag=R->sum=0;
R->lc=Build(l,l+r>>1);
R->rc=Build((l+r>>1)+1,r);
return R;
}
struct Chain {Chain *next;int u,len;}*Head[110001];
inline void Add(int u,int v,int len)
{Chain *tp=new Chain;tp->u=v;tp->next=Head[u];Head[u]=tp;tp->len=len;}
int T[110001];
struct Rec
{
int v,u,l;
Node*Dis;
inline friend bool operator <(Rec a,Rec b)
{return !cmp(a.Dis,b.Dis,1,Max);}
};
priority_queue<Rec>q;
void Dij(int st,int ed)
{
//pre[st]=st;
Pow[0]=1;
for(int i=1;i<=Max;i++)Pow[i]=(Pow[i-1]<<1)%Mod;
q.push((Rec){st,st,0,Build(1,Max)});
while(!pre[ed]&&!q.empty())
{
Rec t=q.top();q.pop();
if(pre[t.u])continue;
bool Hl=false;
pre[t.u]=t.v;
T[t.u]=T[t.v]+1;
Dis[t.u]=t.Dis;
for(Chain *tp=Head[t.u];tp;tp=tp->next)
if(!pre[tp->u])
{
q.push((Rec){t.u,tp->u,tp->len,Add(Dis[t.u],Max-tp->len,Hl,1,Max)});
}
}
}
void SPFA(int st,int ed)
{
vis[st]=true;
done[st]=true;
pre[st]=st;
Q.push(st);
Pow[0]=1;
for(int i=1;i<=Max;i++)Pow[i]=(Pow[i-1]<<1)%Mod;
Dis[st]=Build(1,Max);
while(!Q.empty())
{
int u=Q.front();Q.pop();Node *R=NULL;bool L=false;
for(Chain *tp=Head[u];tp;tp=tp->next)
{
R=Add(Dis[u],Max-tp->len,L,1,Max);
//if(tp->len==2)
// puts("********************************"),pr(R),puts(""),pr(Dis[u]),puts("********************************");
if(done[tp->u]==false||cmp(R,Dis[tp->u],1,Max))
{
//printf("Rec:%d->%d: ",u,tp->u),print(R),puts("");
done[tp->u]=true;
Dis[tp->u]=R;pre[tp->u]=u,T[tp->u]=tp->len;
if(!vis[tp->u])vis[tp->u]=true,Q.push(tp->u);
} //else printf("Far:%d->%d: ",u,tp->u),print(R),puts("");
}
vis[u]=false;
}
}
int stack[110001];
int tot;
int main()
{
int n,m;
read(n),read(m);
for(int i=1;i<=m;i++)
{
int j,k,l;
read(j),read(k),read(l),Add(j,k,l);Add(k,j,l);
}
int s,t;
int res=0;
read(s),read(t);
Dij(s,t);
if(pre[t]==0)return puts("-1"),0;
printf("%d\n",Dis[t]->Hash);
for(t;t!=s;t=pre[t])
stack[++tot]=t,res+=Pow[T[t]],res%=Mod;
printf("%d\n",tot+1);
stack[++tot]=s;
while(tot)
printf("%d ",stack[tot--]);
puts("");
return 0;
}