zoukankan      html  css  js  c++  java
  • Codeforces 464E. The Classic Problem

    Description

    给定一张 (n) 个点,(m) 条边的无向图,求 (S)(T) 的最短路,其中边权都是 (2^k) 的形式
    (n,m,k<=10^5)
    题面

    Solution

    (NOI) 整数类似
    不过此题没有减法,那么复杂度可以均摊
    我们按普通 (dijkstra) 那样跑,把 (dis) 数组改成一棵线段树
    由于每一次只会加上一个数,用主席树维护一下就行了
    对于进位,因为没有减法,所以产生 (k)(1),至少需要 (k) 次操作,暴力改一次就是 (O(1)) 的了
    那么暴力改复杂度就是对的了,代码十分简单
    比较大小的方式就更二分哈希一样:二分到不同的位置,再判断这个位置
    这题本身给了一个 (hash) ,(seed=2,mod=10^9+7) ,也可以过,但最好还是手写的好

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10,mod=1e9+7;
    int n,m,head[N],nxt[N*2],to[N*2],dis[N*2],num=0;
    int S,T,lim,b[N*2],tt=0,rt[N],pre[N];
    inline void link(int x,int y,int z){
    	nxt[++num]=head[x];to[num]=y;head[x]=num;dis[num]=z;
    }
    struct Seg{
    	int ls,rs,w;
    }tr[N*120];
    inline bool comp(int x,int y,int l,int r){
    	if(l==r)return tr[x].w>tr[y].w;
    	int mid=(l+r)>>1;
    	if(tr[tr[x].rs].w==tr[tr[y].rs].w)return comp(tr[x].ls,tr[y].ls,l,mid);
    	return comp(tr[x].rs,tr[y].rs,mid+1,r);
    }
    inline bool add(int x,int &y,int l,int r,int sa){
    	y=++tt;tr[y]=tr[x];
    	if(l==r){
    		tr[y].w=tr[x].w^1;
    		return tr[x].w;
    	}
    	int mid=(l+r)>>1,ret;
    	if(sa>mid)ret=add(tr[x].rs,tr[y].rs,mid+1,r,sa);
    	else{
    		ret=add(tr[x].ls,tr[y].ls,l,mid,sa);
    		if(ret)ret=add(tr[x].rs,tr[y].rs,mid+1,r,mid+1);
    	}
    	tr[y].w=(1ll*tr[tr[y].rs].w*b[mid-l+1]+tr[tr[y].ls].w)%mod;
    	return ret;
    }
    struct data{
    	int x,rt;
    	bool operator <(const data &p)const{return comp(rt,p.rt,0,lim);}
    };
    priority_queue<data>Q;
    inline void dfs(int x,int dep){
    	if(x==S){printf("%d
    %d ",dep,x);return ;}
    	dfs(pre[x],dep+1);
    	printf("%d ",x);
    }
    inline void Output(int x){
    	printf("%d
    ",tr[rt[x]].w);
    	dfs(x,1);exit(0);
    }
    int main(){
      freopen("pp.in","r",stdin);
      freopen("pp.out","w",stdout);
      cin>>n>>m;
      int x,y,z;
      for(int i=1;i<=m;i++){
    	  scanf("%d%d%d",&x,&y,&z);
    	  link(x,y,z);link(y,x,z);lim=max(lim,z);
      }
      lim+=100;
      b[0]=1;for(int i=1;i<=lim;i++)b[i]=1ll*b[i-1]*2%mod;
      cin>>S>>T;
      Q.push((data){S,rt[S]});
      while(!Q.empty()){
    	  data t=Q.top();Q.pop();
    	  if(t.rt!=rt[t.x])continue;
    	  if(t.x==T)Output(T);
    	  for(int i=head[t.x];i;i=nxt[i]){
    		  int u=to[i],RT;
    		  add(t.rt,RT,0,lim,dis[i]);
    		  if(!rt[u] || comp(rt[u],RT,0,lim))
    			  rt[u]=RT,Q.push((data){u,rt[u]}),pre[u]=t.x;
    	  }
      }
      puts("-1");
      return 0;
    }
    
    
  • 相关阅读:
    315,谁来保护手游开发者的利益
    微信小程序之提高应用速度小技巧
    Python-爬虫-Beautifulsoup解析
    Python-爬虫-requests
    Python-form表单标签
    设计模式のTemplatePattern(模板模式)----行为模式
    链接
    python入门007
    007作业
    005作业
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8715902.html
Copyright © 2011-2022 走看看