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. yii使用CFrom调用ajax失败的记录

    在学习配置yii的CFrom的时候,发现怎么也不能让ajax生效,后来看文档后 ,终于发现了问题的所在. 问题配置文件如下 public function getUserConfig(){ retur ...

  2. Unite 2017 干货整理 优化篇

    Unite 2017 干货整理 优化篇 2017年05月16日 将Unite 2017的一些演讲做了整理.  本篇有内存,CPU.GC.UI.渲染性能指标.Tips几个小节.  内容持续整理中. 内存 ...

  3. 动手写一个简单版的谷歌TPU

    谷歌TPU是一个设计良好的矩阵计算加速单元,可以很好的加速神经网络的计算.本系列文章将利用公开的TPU V1(后简称TPU)相关资料,对其进行一定的简化.推测和修改,来实际编写一个简单版本的谷歌TPU ...

  4. 关于HTML5画布canvas的功能

    一.画布的使用 1.首先创建一个画布(canvas) <canvas id=”myCanvas” width=”200” height=”100” style=”border:1px solid ...

  5. Macbook 修复Office Excel 异常问题

    manbook 版本的office excel 在一次崩溃后,每次打开excel 文件都会弹出以下烦人的错误告警,并且每次都会重新打开很多过去保存过的excel 文件. “在应用程序意外退出之前,Ex ...

  6. W3C标准以及规范

    1.什么是DOCTYPE DOCTYPE是document type(文档类型)的简写,用来说明你用的XHTML或者HTML是什么版本.其中的DTD(例如xhtml1-transitional.dtd ...

  7. eclipse中windows下的preferences左栏没有tomcat?

    是因为缺少eclipse for tomcat 插件,到http://www.eclipsetotale.com/tomcatPlugin.html此网站下载,我的eclipse版本是4.4版本的,所 ...

  8. VUE中实现iview的图标效果时遇到的一个问题

    [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available ...

  9. ES6新特性使用小结(四)

    十一.Proxy .Reflect ①.Proxy 的概念和常用方法 { let obj = { //1.定义原始数据对象 对用户不可见 time: '2017-09-20', name: 'net' ...

  10. openSUSE 跨版本升级

    准备工作 此方法通过网络跨版本升级,适合 Leap 升级到下一个发行版(如 42.2 升级到 42.3),也适合 Leap 升级为 Tumbleweed.首先必须确定升级的时候有足够的时间.靠谱的更新 ...