codeforces464E The Classic Problem -- 最短路+主席樹+Hash
題目大意:
求
程式碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
#define N 100010
#define P 1000000007
#define INF 1e6
typedef unsigned long long ull;
struct Edge{
int t,nx,w;
}e[N<<1];
struct Node{
ull w;
int l,r,f;
}c[N*280];
struct Interval{
int l,r;
Interval(int l=0,int r=0):l(l),r(r){}
bool operator < (Interval a)const{
return l<a.l||(l==a.l&&r<a.r);
}
};
map<Interval,int >Map;
ull p[N+100];
int i,j,k,n,m,h[N],x,y,z,d[N],Num,t,M,Pre[N],Cnt,g[N],B;
bool b[N];
inline bool Cmp(int x,int y,int l,int r){
if(l==r)return c[x].w>c[y].w;
int Mid=l+r>>1;
if(c[c[x].r].w==c[c[y].r].w)return Cmp(c[x].l,c[y].l,l,Mid);
return Cmp(c[x].r,c[y].r,Mid+1,r);
}
struct A{
int Rt,f;
A(int Rt=0,int f=0):Rt(Rt),f(f){}
bool operator < (A a)const{
return Cmp(Rt,a.Rt,1,M);
}
}Tmp;
priority_queue<A>Q;
inline int Max(int x,int y){
return x<y?y:x;
}
inline int Min(int x,int y){
return x<y?x:y;
}
inline void Add(int x,int y,int z){
e[++t].t=y;e[t].nx=h[x];h[x]=t;e[t].w=z;
}
inline void Up(int x){
c[x].w=c[c[x].l].w*7+c[c[x].r].w*11;
c[x].f=c[c[x].l].f<INF?c[c[x].l].f:c[c[x].r].f;
}
inline void Build(int& x,int l,int r){
x=++Num;Map[Interval(l,r)]=x;
if(l==r){
c[x].f=l;
return;
}
int Mid=l+r>>1;
Build(c[x].l,l,Mid);
Build(c[x].r,Mid+1,r);
Up(x);
}
inline int Update2(int x,int l,int r,int y){
int z=++Num;c[z]=c[x];
if(l==r){
c[z].w=p[l];
c[z].f=INF;
return z;
}
int Mid=l+r>>1;
if(y<=Mid)c[z].l=Update2(c[x].l,l,Mid,y);else c[z].r=Update2(c[x].r,Mid+1,r,y);
Up(z);
return z;
}
inline int Update3(int x,int l,int r,int L,int R){
if(l>=L&&r<=R)return Map[Interval(l,r)];
int Mid=l+r>>1,y=++Num;c[y]=c[x];
if(Mid>=L)c[y].l=Update3(c[x].l,l,Mid,L,R);
if(Mid<R)c[y].r=Update3(c[x].r,Mid+1,r,L,R);
Up(y);
return y;
}
inline int Find(int x,int l,int r,int y){
if(l==r)return c[x].f;
int Mid=l+r>>1;
if(y<=Mid)return Min(Find(c[x].l,l,Mid,y),c[c[x].r].f);
return Find(c[x].r,Mid+1,r,y);
}
inline int Update1(int x,int y){
int z=Find(x,1,M,y);
int a1=Update2(x,1,M,z);
if(z>y)a1=Update3(a1,1,M,y,z-1);
return a1;
}
inline int Getval(int x,int l,int r){
if(l==r){
int ret=c[x].w?B:0;
return B=(B<<1)%P,ret;
}
int Mid=l+r>>1;
return (Getval(c[x].l,l,Mid)+Getval(c[x].r,Mid+1,r))%P;
}
int main(){
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&z),Add(x,y,++z),Add(y,x,z),M=Max(M,z);
for(i=1;1<<i<n;i++);M+=i;
for(i=p[0]=1;i<=M;i++)p[i]=p[i-1]*5;
scanf("%d%d",&x,&y);
if(x==y){
printf("0\n1\n%d\n",x);
return 0;
}
Build(d[x],1,M);
Q.push(A(d[x],x));
while(!Q.empty()){
Tmp=Q.top();Q.pop();
if(d[Tmp.f]!=Tmp.Rt)continue;
for(int i=h[Tmp.f];i;i=e[i].nx){
z=Update1(d[Tmp.f],e[i].w);
if(!b[e[i].t]||Cmp(d[e[i].t],z,1,M)){
b[e[i].t]=1;d[e[i].t]=z;Pre[e[i].t]=Tmp.f;
Q.push(A(z,e[i].t));
}
}
}
if(!b[y])printf("-1\n");else{
B=1;
printf("%d\n",Getval(d[y],1,M));
for(i=y;i!=x;i=Pre[i])g[++Cnt]=i;
printf("%d\n%d ",Cnt+1,x);
for(i=Cnt;i;i--)printf("%d ",g[i]);
}
return 0;
}
相關推薦
codeforces464E The Classic Problem -- 最短路+主席樹+Hash
題目大意: 求s到t的最短路,邊權為2xi,xi≤105。 程式碼: #include<iostream> #include<cstdio> #include<cstring> #include<alg
Codeforces 464E The Classic Problem (最短路 + 主席樹 + hash)
The jks main hup def cmp rhs sign code 題意及思路 這個題加深了我對主席樹的理解,是個好題。每次更新某個點的距離時,是以之前對這個點的插入操作形成的線段樹為基礎,在O(logn)的時間中造出了一顆新的線段樹,相比直接創建n顆線段樹更省
[最短路 主席樹 Hash] Codeforces 464E #265 (Div. 1) E. The Classic Problem
很棒的資料結構練習題 因為邊權太大了 我們不能直接儲存 我們用主席樹! 比較直接從高位到低位找第一個不同的位 可以Hash下 每次加法 我們找到這一位之後第一個0 那麼0變為1 0之前一連串1都變成0 這裡有個小trick可以不用打標記 我們先建一棵全
[最短路 && 主席樹維護HASH] 51nod1863 Travel
傳送門 把一條路徑上的點值按排名順序排序,那麼路徑的優劣就是字典序。 相當於是求一條字典序最大的路徑。 最長路 然後就是老套路,用主席樹來維護hash,就可以在O(log)的時間裡比較兩個串的字典序,然後就套最短路就可以了 用對優化的DIJ複雜度就是O(
CodeForces 464E The Classic Problem | 呆克斯歘 主席樹維護高精度
ring 問題: || con .html 每次 tin -- ace 題意描述 有一個\(n\)點\(m\)邊的無向圖,第\(i\)條邊的邊權是\(2^{a_i}\)。求點\(s\)到點\(t\)的最短路長度(對\(10^9 + 7\)取模)。 題解 思路很簡單——用
HDU1142 A Walk Through the Forest(最短路+DAG)
input ica highlight iss diff wan before star length A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 6
最短路 BZOJ3694 樹鏈剖分+線段樹
OS 情況 ostream 最小值 down from == spa sizeof 分析: 樹剖裸題,[Usaco2009 Jan]安全路經Travel 的簡化版 剖開最短路樹,遍歷每一條沒在最短路樹上的邊。 這種情況下,有且僅有u到v路徑上,出來lca之外的點能夠通
HDU 1142 A Walk Through the Forest(最短路+記憶化搜索)
大於 take tin href init sizeof itl any problem A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/327
CF 464E The Classic Problem
進行 dijk hid htm operator logs one http 在線 補一補之前聽課時候的題。 考慮使用dij算法求最短路,因為邊權存不下,所以考慮用主席樹維護二進制位,因為每一次都只會在一個位置進行修改,所以可以暴力進位,這樣均攤復雜度是對的。 《算法導
gym 101064 G.The Declaration of Independence (主席樹)
直接 兩個 enc upd () class 我們 lar 元素 題目鏈接: 題意: n個操作,有兩種操作: E p c 在序號為p的隊列尾部插入c得到新的隊列,序號為i D p 查詢並刪除序號為p的隊列頂部的元素,得到序號為i的新隊列 思路: 需要
[最短路/線段樹大法優化DIJ] 【模板】單源最短路徑(標準版)
洛谷原題 這題我自己看了STL優先佇列後試了試優化DIJ演算法,但我這個菜比只有32分... 還是老老實實用線段樹吧! 自己寫的程式,反正AC了,線段樹大法好! 具體見程式碼 #include<bits/stdc++.h> using namespace std; long lon
[bzoj2725]故鄉的夢——最短路+線段樹 dalaos' blogs Some Links
題目大意: 給定一個帶權無向圖,每次詢問刪除一條邊之後從S到T的最短路是多少?(各個詢問之間獨立) 思路: 如果刪除的邊不在最短路中或者可以被替換,那麼答案即為最短路。 如果刪除的邊在最短路中並且不可以被替換,考慮將這條邊刪除的新圖: 假設原來的最短路為
The Doors(幾何+最短路,好題)
The Doors http://poj.org/problem?id=1556 Time Limit: 1000MS Memory Limit: 10000K Total Submis
CF 1051F The Shortest Statement (最短路)
題目大意:一個無向連通圖,n個點m條邊,n<=1e5,m-n<=20,q個詢問,q<=1e5,求u和v之間的最短路 發現邊只比點多20個,所以可以把圖當成一棵樹,求出圖的最小生成樹 對於一個詢問,最短路徑可能是兩個點的樹上最小距離,但最短路徑也有可能經過未被加入最小生成樹的邊 那怎麼辦
洛谷3783 SDOI2017 天才黑客(最短路+虛樹+邊轉點+線段樹優化建圖)
題目連結 成功又一次自閉了 怕不是豬國殺之後最自閉的一次 一看到最短路徑。 我們就能推測這應該是個最短路題 現在考慮怎麼建圖 根據題目的意思,我們可以發現,在本題中,邊與邊之間存在一些轉換關係,但是點與點之間並不存在。 那麼我們考慮 邊轉點,點轉邊。 每一條邊拆成
Codeforces 786B Legacy 最短路+線段樹
不錯的題目,這次不偷qsc得了,偷個別人的 傳送門 題目意思很簡單,就是你有三種操作: 1 u v w 從u向v連一條權值為w的有向邊 2 u L R w 從u向L至R的所有結點連一條權值為w的有向邊 3 u L R w 從L至R的所有結點向u連一條權值為w的
[bzoj2725]故鄉的夢——最短路+線段樹
題目大意: 給定一個帶權無向圖,每次詢問刪除一條邊之後從S到T的最短路是多少?(各個詢問之間獨立) 思路: 如果刪除的邊不在最短路中或者可以被替換,那麼答案即為最短路。 如果刪除的邊在最短路中並且不可以被替換,考慮將這條邊刪除的新圖: 假設原來的最短路為S−&a
Codechef Aug2017 #Walks on the binary tree -- 主席樹+Hash
傳送門 每次答案增加的值就是 n - 之前出現的數與 X 的 LCP 最大值。 而與 X 的 LCP 最大的點在 dfs 序上與 X 的距離最近。而在滿二叉樹上 X 在 dfs 序上的位置就等於 X 。 於是可以用 set 維護所有出現過的點,加入 X 時
Educational Codeforces Round 51 (Rated for Div. 2) F. The Shortest Statement (最短路+LCA)
原題地址:http://codeforces.com/contest/1051/problem/F 題意:給你nnn個點,mmm條邊。m−n<=20m-n<=20m−n<=20。保證圖連通 問你任意兩點的最短距離是多少。 思路:
bzoj4435: [Cerc2015]Juice Junctions(最小割樹+hash)
ostream printf tdi amp mes moto blog pen .com 傳送門 首先最大流等於最小割,那麽可以轉化為最小割樹來做(不知道什麽是最小割樹的可以看看這題->這裏) 具體的做法似乎是$hash[i][j]$表示最小割為$i$時點