倍增字典序 拓撲排序 尋找數字

2021-10-23 14:45:31 字數 1700 閱讀 5045

這裡介紹一種雜湊+倍增判斷字典序的方法,比較套路但不容易想到。

設f [x

][i]

f[x][i]

f[x][i

]表示節點 x

xx 往回跳 2

i2^i

2i所到達的點,w[x

][i]

w[x][i]

w[x][i

] 表示節點 x

xx 到 f[x

][i]

f[x][i]

f[x][i

] 路徑中的最小值。

那麼我們對於節點 u

uu 和節點 v

vv 如何判斷往回的字典序誰優秀呢?

然後這道題這需要建立反圖,拓撲排序即可。

如何判斷環呢?顯然,只要拓撲排序中沒有進入佇列,說明這個節點是環上的節點或從環上出來的點。直接特判即可。

這太妙了

#include

using namespace std;

const

int n =

1e6+10;

const

int p =

998244353

;int n, m;

int in[n]

, f[n][25

], w[n][25

], res[n]

, power[n]

, dis[n]

;vector < pair<

int,

int>

> a[n]

;int

read

(void

)void

topsort

(void

)for

(int i=

0;i.size()

;++i)

else

if(dis[x]+1

== dis[y])if

(w[v][0

]< w[u][0

]) f[y][0

]= x;}}

in[y]--;

if(in[y]==0

) q.

push

(y);}}

for(

int i=

1;i<=n;

++i)

if(in[i]

>

0) res[i]=-

1;return;}

intmain

(void))

, in[x]++;

} power[0]

=1;for

(int i=

1;i<=n;

++i) power[i]

=1ll

* power[i-1]

*131

% p;

topsort()

;for

(int i=

1;i<=n;

++i)

res[i]==-

1?puts

("infinity"):

printf

("%d\n"

, res[i]);

return0;

}

拓撲排序 字典序

1.用優先佇列維護 2.從後往前排序,每次判斷節點的出度,出度 0 進入優先佇列.3.用vector陣列做鄰接表表示整個圖 include include include include include using namespace std const int maxn 30005 vector ...

優先佇列實現字典序最小的拓撲排序

煩人的依賴 時間限制 c c 1秒,其他語言2秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld 題目描述 ubuntu20.04 正式發布了,zls 是乙個作死小能手,於是他決定嘗試一下這個船新版本。好不容易裝完系統,zls 想要給他的系統裝一些常...

字典樹 拓撲排序 第一!

bessie一直在研究字串。她發現,通過改變字母表的順序,她可以按改變後的字母表來排列字串 字典序大小排列 例如,bessie發現,對於字串串 omm moo mom 和 ommnom 她可以使用標準字母表使 mom 排在第乙個 即字典序最小 她也可以使用字母表 abcdefghijklonmpqr...