E. The Classic Problem

http://codeforces.com/problemset/problem/464/E

题意:给你一张无向带权图,求S-T的最短路,并输出路径。边权为2^xi。xi≤105,n≤105,m≤105.

想法:边权太大了,可以用数组按二进制存下来。带高精度跑太费事了。

观察一下,这里距离的更新:c=(a,b),用dis[a]更新dis[b]

①dis[b][c]=0,直接赋为1.只有一个数字改变。

②dis[b][c]=1,需要进位。考虑极端情况数据,xi都是一个数,那么需要进位O(m/2+m/4+m/8+...+1)≈O(m)

所以总改变次数为O(m),使用主席树维护这个二进制数组。

然后比较大小,可以在主席树上二分,如果左儿子一样就往右儿子走,反之走左儿子。判断是否一样可以用Hash。一次比较为O(logm).

于是dijkstra+heap+主席树:

空间复杂度O(mlogm).

时间复杂度O(mlog^2m).

ps:因为有进位要给主席树预留logm个空间。

 #include<cstdio>
#include<algorithm>
const int len(),lem(),HP(),MP(),RP();
struct ChairManTree{int nx[],sum;}tree[lem+];
int stot,root[len+];int H[len+],b[len+],tp;
struct Node{int nd,nx,co;}bot[len*+];
int tot,first[len+];
int n,m,v[len+],u[len+],x[len+],axle[len+],up,big,s,t,last[len+];
void add(int a,int b,int c){bot[++tot]=(Node){b,first[a],c};first[a]=tot;}
int two(int x)
{
int l=,r=up,ans=,mid;
while(l<=r)
if(axle[mid=(l+r)>>]>=x){ans=mid;l=mid+;}else r=mid-;
return ans;
}
void update(int k,int l,int r)
{
tree[k].sum=(1ll*tree[tree[k].nx[]].sum*H[(r-l+)>>]+tree[tree[k].nx[]].sum)%MP;
}
void build(int k,int l,int r,int x)
{
if(l==r){tree[k].sum=x;return;}
int mid=(l+r)>>;
tree[k].nx[]=++stot;build(stot,l,mid,x);
tree[k].nx[]=++stot;build(stot,mid+,r,x);
update(k,l,r);
}
int cmp(int k1,int k2)//-:k1<k2,+:k2>k1,0:k1=k2,return +-pos
{
int l=,r=up+,mid;
while(l!=r)
{
mid=(l+r)>>;
if(tree[tree[k1].nx[]].sum==tree[tree[k2].nx[]].sum)
k1=tree[k1].nx[],k2=tree[k2].nx[],l=mid+;
else k1=tree[k1].nx[],k2=tree[k2].nx[],r=mid;
}
if(tree[k1].sum==tree[k2].sum)return ;
if(tree[k1].sum<tree[k2].sum)return -l;
return l;
}
int insert(int k,int l,int r,int &x)
{
int z=++stot;
if(l==r)
{
if(tree[k].sum)tree[z].sum=,x--;//进位
else tree[z].sum=;return z;
}
int mid=(l+r)>>,tmp;tree[z]=tree[k];
if(x>mid){tmp=insert(tree[k].nx[],mid+,r,x);tree[z].nx[]=tmp;}
if(x<=mid){tmp=insert(tree[k].nx[],l,mid,x);tree[z].nx[]=tmp;}
update(z,l,r);
return z;
}
void dfs(int x,int l,int r)
{
if(l==r){b[l]=tree[x].sum;return;}
int mid=(l+r)>>;
dfs(tree[x].nx[],l,mid);
dfs(tree[x].nx[],mid+,r);
}
struct data
{
int x,y;
bool operator <(const data &A)const//默认小根堆
{
return (cmp(x,A.x)>);
}
}q[len*+];int qfree;
void Dijkstra()
{
for(int i=;i<=n;i++)root[i]=root[n+];
root[s]=root[];q[qfree=]=(data){root[s],s};
while(qfree)
{
data now=q[];std::pop_heap(q+,q++qfree);qfree--;
while(root[now.y]!=now.x&&qfree){now=q[];std::pop_heap(q+,q++qfree);qfree--;}
if(root[now.y]!=now.x&&!qfree)break;
for(int v=first[now.y];v;v=bot[v].nx)
{
int tmp=insert(root[now.y],,up+,bot[v].co);
int pos=cmp(tmp,root[bot[v].nd]);
if (pos>=)continue;
last[bot[v].nd]=now.y;
root[bot[v].nd]=tmp;
q[++qfree]=(data){root[bot[v].nd],bot[v].nd};
std::push_heap(q+,q++qfree);
}
}
}
void put()
{
if(root[t]==root[n+])printf("-1");
else
{
if(tree[root[t]].sum==tree[root[]].sum)printf("0\n");
else
{
dfs(root[t],,up+);
int tmp=,j=,l=;
for(int i=up;i>=;i--)
{
while(l<axle[i]){l++;j=(j+j)%RP;}
tmp=(tmp+1ll*j*b[i])%RP;
}
printf("%d\n",tmp);
}
int now=t;b[tp=]=t;
while(last[now])
{
now=last[now];
b[++tp]=now;
}
printf("%d\n",tp);
for(int i=tp;i>=;i--)
printf("%d ",b[i]);
}
}
bool cmp2(int a,int b){return a>b;}
int main()
{
freopen("C.in","r",stdin);
freopen("C.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d%d%d",v+i,u+i,x+i);
if(x[i]>big)big=x[i];
}
scanf("%d%d",&s,&t);
for(int i=;i<=big+;i++)axle[i]=big+-i;up=big+;
H[]=;for(int i=;i<=up+;i++)H[i]=(1ll*H[i-]*HP)%MP;
for(int i=;i<=m;i++)
{
x[i]=two(x[i]);
add(v[i],u[i],x[i]);
add(u[i],v[i],x[i]);
}
root[]=++stot;build(root[],,up+,);//zero
root[n+]=++stot;build(root[n+],,up+,);//INF
Dijkstra();
put();
return ;
}

Codeforces 464E #265 (Div. 1) E. The Classic Problem 主席树+Hash的更多相关文章

  1. Codeforces Round #321 (Div. 2) E. Kefa and Watch 线段树hash

    E. Kefa and Watch Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/580/prob ...

  2. Codeforces Round #265 (Div. 1) C. Substitutes in Number dp

    题目链接: http://codeforces.com/contest/464/problem/C J. Substitutes in Number time limit per test 1 sec ...

  3. Codeforces Round #265 (Div. 2) C. No to Palindromes! 构建无回文串子

    http://codeforces.com/contest/465/problem/C 给定n和m,以及一个字符串s,s不存在长度大于2的回文子串,如今要求输出一个字典比s大的字符串,且串中字母在一定 ...

  4. Codeforces Round #265 (Div. 2) E. Substitutes in Number

    http://codeforces.com/contest/465/problem/E 给定一个字符串,以及n个变换操作,将一个数字变成一个字符串,可能为空串,然后最后将字符串当成一个数,取模1e9+ ...

  5. Codeforces Round #265 (Div. 2) D. Restore Cube 立方体判断

    http://codeforces.com/contest/465/problem/D 给定8个点坐标,对于每个点来说,可以随意交换x,y,z坐标的数值.问说8个点是否可以组成立方体. 暴力枚举即可, ...

  6. Codeforces Round #265 (Div. 2) C. No to Palindromes! 构造不含回文子串的串

    http://codeforces.com/contest/465/problem/C 给定n和m,以及一个字符串s,s不存在长度大于2的回文子串,现在要求输出一个字典比s大的字符串,且串中字母在一定 ...

  7. Codeforces Round #265 (Div. 2) D. Restore Cube 立方体推断

    http://codeforces.com/contest/465/problem/D 给定8个点坐标.对于每一个点来说,能够任意交换x.y,z坐标的数值. 问说8个点能否够组成立方体. 暴力枚举就可 ...

  8. Codeforces Round #265 (Div. 2)

    http://codeforces.com/contest/465 rating+7,,简直... 感人肺腑...............蒟蒻就是蒟蒻......... 被虐瞎 a:inc ARG 题 ...

  9. Codeforces Round #265 (Div. 2) E

    这题说的是给了数字的字符串 然后有n种的操作没次将一个数字替换成另一个字符串,求出最后形成的字符串的 数字是多大,我们可以逆向的将每个数推出来,计算出他的值和位数记住位数用10的k次方来记 1位就是1 ...

随机推荐

  1. 怎么查看linux系统是32还是64

    1.getconf LONG_BIT or getconf WORD_BIT例如:2.file /bin/ls例如: 查看linux的版本:

  2. "Mysql has gone away"的几种可能

    现象: 在本地利用Flask自带的WSGI服务进行调试没有问题后,通过Gunicorn进行部署. 但是在一晚上没有访问之后,第二天再次访问会出现500(Internal error). 原因: 通过追 ...

  3. E20190418-hm

    distinct adj. 明显的,清楚的; 卓越的,不寻常的; 有区别的; 确切的; predicate  vt. 断言,断定; 宣布,宣讲; 使基于; n. 谓语; 述语;

  4. python_文件目录的操作

    Python文件的主要操作 主要包括: 1,创建一个文件 2,删除一个文件 3,创建一个目录 4,删除一个目录 5,拷贝,重命名,查看文件大小 6,列出某个目录下文件的数量 7,递归打印某个目录下的所 ...

  5. apply的使用技巧

    1.什么是apply?他和call有什么区别? apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性. Function.apply(obj,args)方法能接收两个参数 obj:这个对象 ...

  6. 浅谈Unity的渲染优化(1): 性能分析和瓶颈判断(上篇)

    http://www.taidous.com/article-667-1.html 前言 首先,这个系列文章做个大致的介绍,题目"浅谈Unity",因为公司和国内大部分3D手游开发 ...

  7. 2014-10-28 NOIP模拟赛

    Porble 1时间与空间之旅(tstrip.*) 题目描述 公元22××年,宇宙中最普遍的交通工具是spaceship.spaceship的出现使得星系之间的联系变得更为紧密,所以spaceship ...

  8. 洛谷2105 k皇后

    P2105 K皇后 题目描述 小Z最近捡到了一个棋盘,他想在棋盘上摆放K个皇后.他想知道在他摆完这K个皇后之后,棋盘上还有多少了格子是不会被攻击到的. (Ps:一个皇后会攻击到这个皇后所在的那一行,那 ...

  9. Apache为本地主机配置多个网站根目录详解

    Author:KillerLegend Date:2014.5.27 From:http://blog.csdn.net/killerlegend/article/details/27195445 - ...

  10. 2018最新苹果APP上架App Store流程(超详细)

    本文转发:https://blog.csdn.net/xxw888/article/details/73618837 2018最新整理iOS app上架app详细教程 上架iOS需要一个付费688的开 ...