WA on test 9求调/kk
查看原帖
WA on test 9求调/kk
172370
fzj2007楼主2021/11/6 08:55

RT,第 99 个点 WA 了,最短路长度错误/yun

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<cmath>
#include<iomanip>
#include<string>
#include<cstring>
#include<set>
#include<stack>
#include<queue>
#include<bitset>
using namespace std;
namespace IO{
    template<typename T>inline void read(T &x){
        x=0;
        char ch=getchar();
        bool flag=0;
        while(ch<'0'||ch>'9') flag=flag||(ch=='-'),ch=getchar();
        while(ch>='0'&&ch<='9') x=x*10+(ch^'0'),ch=getchar();
        if(ch!='.'){
            x=flag?-x:x;
            return;
        }
        double Base=0.1;
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') x=x+Base*(ch^'0'),Base/=10.0,ch=getchar();
        x=flag?-x:x;
    }
    template<typename T>void prt(T x){
        if(x>9) prt(x/10);
        putchar(x%10+'0');
    }
    template<typename T>inline void put(char ch,T x){
        if(x<0) putchar('-'),x=-x;
        prt(x);
        putchar(ch);
    }
    const int DM[10]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
    inline void putd(char ch,double x,int w){
        if(x<0) putchar('-'),x=-x;
        if(!w){
            put(ch,(int)(x+0.5));
            return;
        }
        int prex=(int)x;
        x-=(int)x;
        x*=DM[w];
        x+=0.5;
        int nowx=(int)x,now=0;
        if(nowx>=DM[w]) nowx=0,prex++;
        put('.',prex);
        int xx=nowx;
        if(!xx) now=1;
        else while(xx) xx/=10,now++;
        now=w-now;
        while(now--) putchar('0');
        put(ch,nowx);
    }
    inline void putstr(string s){
        for(int i=0;i<s.length();i++) putchar(s[i]);
    }
}
using namespace IO;
#define M 6000005
#define N 500100
#define Maxn 100005
#define hshmod 10000000007
#define ull unsigned long long
#define hshbase 2
#define khshbase 13
#define khshmod 193872937
ull bs[N],kb[N];
struct edge{
	int v,nxt,w;
}e[N<<1];
int n,m,head[N],cnt,S,T,rt[N];
inline void add(int u,int v,int w){
	e[++cnt]=(edge){v,head[u],w},head[u]=cnt;
}
inline ull mul(ull x,ull y,ull mod){
	return x*y%mod;
}
inline ull add(ull x,ull y,ull mod){
	return x+y>=mod?x+y-mod:x+y;
}
struct SegmentTree{
	int idx=0;
	struct node{
		int ls,rs,siz;
		//左右儿子,1的个数 
		ull hsh;
		ull key;//答案和哈希
		inline bool operator==(const node &b)const{
			return siz==b.siz&&hsh==b.hsh&&key==b.key;
		}
		//hsh值 
	}t[M];//左边(下标小的)是低位,右边是高位 
	#define lc(x) t[x].ls
	#define rc(x) t[x].rs
	inline void init(){
		bs[0]=kb[0]=1;
		for(int i=1;i<=Maxn;i++)
			bs[i]=mul(bs[i-1],hshbase,hshmod),kb[i]=mul(kb[i],khshbase,khshmod);
	}
	inline void push_up(int x){
		t[x].siz=t[lc(x)].siz+t[rc(x)].siz;
		t[x].hsh=add(t[lc(x)].hsh,t[rc(x)].hsh,hshmod);
		t[x].key=add(t[lc(x)].key,t[rc(x)].key,(ull)khshmod);
	}
	int build(int l,int r,int val){//新建一个全0或全1的树 
		int x=++idx; 
		if(l==r){
			t[x].hsh=mul(bs[l],val,hshmod);
			t[x].key=mul(kb[l],val,khshmod);
			t[x].siz=val;
			return x;
		}
		int mid=l+r>>1;
		lc(x)=build(l,mid,val),rc(x)=build(mid+1,r,val);
		push_up(x);
		return x;
	}
	int query(int x,int l,int r,int ql,int qr){//查询区间内有多少个1 
		if(ql<=l&&qr>=r) return t[x].siz;
		int mid=l+r>>1,res=0;
		if(ql<=mid) res+=query(lc(x),l,mid,ql,qr);
		if(qr>mid) res+=query(rc(x),mid+1,r,ql,qr);;
		return res;
	}
	int getpos(int x,int l,int r,int pos){//找到当前位置右边第一个0的位置
		//此函数用于找到全1段的终点(处理进位) 
		if(l==r) return l;
		int mid=l+r>>1;
		if(pos>mid) return getpos(rc(x),mid+1,r,pos);
		if(query(lc(x),l,mid,pos,mid)==mid-pos+1/*如果左边剩下的位置都是1*/) return getpos(rc(x),mid+1,r,pos);
		return getpos(lc(x),l,mid,pos);
	}
	int update(int pre,int l,int r,int pos){//在pre版本基础上单点赋值为1 
		int x=++idx;
		t[x]=t[pre];
		if(l==r){
			t[x].siz=1;
			t[x].hsh=bs[l];
			t[x].key=kb[l];
			return x;
		}
		int mid=l+r>>1;
		if(pos<=mid) lc(x)=update(lc(pre),l,mid,pos);
		else rc(x)=update(rc(pre),mid+1,r,pos);
		push_up(x);
		return x;
	}
	int move(int x,int y,int l,int r,int ql,int qr){//区间赋值为0 
		if(qr<l||ql>r) return x;
		if(ql<=l&&qr>=r) return y;
		int mid=l+r>>1;
		int now=++idx;
		lc(now)=move(lc(x),lc(y),l,mid,ql,qr);
		rc(now)=move(rc(x),rc(y),mid+1,r,ql,qr);
		push_up(now);
		return now;
	}
	int Add(int root,int val){//root版本加上2^val
		int pos=getpos(root,0,Maxn,val);
		int now=update(root,0,Maxn,pos);
		if(pos!=val) now=move(now,rt[0],0,Maxn,val,pos-1);
		return now;
	}
	int compare(int x,int y,int l,int r){//查询x是否小于等于y 
		if(l==r) return t[x].siz<=t[y].siz;
		int mid=l+r>>1;
		if(t[rc(x)]==t[rc(y)]) return compare(lc(x),lc(y),l,mid);
		else return compare(rc(x),rc(y),mid+1,r);
	}
}s;
struct left_tree{
	int siz,root,idx;
	struct node{
		//当前点,权值(线段树的根),左右儿子,深度 
		int x,rt,ls,rs,dep;
	}t[N];
	#define lc(x) t[x].ls
	#define rc(x) t[x].rs
	int merge(int x,int y){//左偏树合并 
		if(!x||!y) return x|y;
		if(s.compare(t[y].rt,t[x].rt,0,Maxn)) swap(x,y);
		rc(x)=merge(rc(x),y);
		if(t[rc(x)].dep>t[lc(x)].dep) swap(lc(x),rc(x));
		t[x].dep=t[rc(x)].dep+1;
		return x;
	}
	inline void push(int _x,int _rt){
		siz++;
		t[++idx]=(node){_x,_rt,0,0,0};
		root=merge(root,idx);
	}
	inline void pop(){
		siz--;
		root=merge(lc(root),rc(root));
	}
	inline int top(){
		return t[root].x;
	}
	inline bool empty(){
		return siz==0;
	}
}q;
bool vis[N];
int dis[N],pre[N],st[N],tp;
inline void dijkstra(){
	int inf=s.build(0,Maxn,1);//初始一个极大值 
	for(int i=1;i<=n;i++) rt[i]=inf;
	rt[0]=rt[S]=s.build(0,Maxn,0);//起点赋成0
	q.push(S,rt[S]);
	while(!q.empty()){
		int x=q.top();
		q.pop();
		if(vis[x]) continue;
		vis[x]=1;
		for(int i=head[x];i;i=e[i].nxt){
			int v=e[i].v;
			if(vis[v]) continue;
			int trans=s.Add(rt[x],e[i].w);
			if(s.compare(rt[v],trans,0,Maxn)) continue;
			rt[v]=trans,pre[v]=x;
			q.push(v,rt[v]);
		}
	} 
	if(rt[T]==inf) return put('\n',-1),void();
	put('\n',s.t[rt[T]].hsh%hshmod);
	for(int x=T;x!=S;x=pre[x]) st[++tp]=x;
	st[++tp]=S;
	put('\n',tp);
	while(tp) put(' ',st[tp--]);
}
int main(){
	read(n),read(m);
	s.init();
	for(int i=1,u,v,w;i<=m;i++) read(u),read(v),read(w),add(u,v,w),add(v,u,w);
	read(S),read(T);
	dijkstra();
	
	return 0;
}
2021/11/6 08:55
加载中...