CF464E

CF464E_第1张图片

论省选前的智商

很奇怪啊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;
}

你可能感兴趣的:(CF464E)