日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AcWing 164. 可达性统计

發布時間:2025/3/14 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AcWing 164. 可达性统计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

給定一張N個點M條邊的有向無環圖,分別統計從每個點出發能夠到達的點的數量。

輸入格式

第一行兩個整數N,M,接下來M行每行兩個整數x,y,表示從x到y的一條有向邊。

輸出格式

輸出共N行,表示每個點能夠到達的點的數量。

數據范圍

1N,M30000


顯然可以用拓撲排序+狀態壓縮來做, 用一個n位的二進制數存每一個f[x], 其中第i位是1表示x能到i,0則不能到i, 這樣就相當于存在x 到 y的一條邊,f[x] |= f[y], 再預處理處拓撲序, 反向枚舉, 最后判斷每個f[i]中的個數, 但有一個bug就是, 就算unsigned long long 二進制下只有64位, 這里就有一個小小的干貨:

?

關于狀態壓縮 bitset容器:
轉載:https://oi-wiki.org/ds/stl/bitset/
介紹?
std :: bitset 是標準庫中的一個固定大小序列,其儲存的數據只包含 0/1

?

眾所周知,由于內存地址是按字節即 byte 尋址,而非比特 bit ,

?

我們一個 bool 類型的變量,雖然只能表示 0/1 , 但是也占了 1byte 的內存

?

bitset 就是通過固定的優化,使得一個字節的八個比特能分別儲存 8 位的 0/1

?

對于一個 4 字節的 int 變量,在只存 0/1 的意義下, bitset 占用空間只是其

?

在某些情況下通過 bitset 可以使你的復雜度除以 32

?

當然, vector 的一個特化 vector<bool> 的儲存方式同 bitset 一樣,區別在于其支持動態開空間,

?

bitset 則和我們一般的靜態數組一樣,是在編譯時就開好了的。

?

那么為什么要用 bitset 而非 vector<bool> ?

?

通過以下的介紹,你可以更加詳細的看到 bitset 具備的方便操作

?

#include <bitset> // 包含 bitset 的頭文件
運算符?
operator[] : 訪問其特定的一位

?

operator ==/!= : 比較兩個 bitset 內容是否完全一樣

?

operator &=/|=/^=/~ : 進行按位與/或/異或/取反操作

?

operator <</>>/<<=/>>= : 進行二進制左移/右移

?

operator <</>> : 流運算符,這意味著你可以通過 cin/cout 進行輸入輸出

?

vector<bool> 只具有前兩項

?

成員函數?
test() : 它和 vector 中的 at() 的作用是一樣的,和 [] 運算符的區別就是越界檢查
count() : 返回 true 的數量
set() : 將整個 bitset 設置成 true , 你也可以傳入參數使其設置成你的參數
reset() : 將整個 bitset 設置成 false
flip() : 翻轉該位 (0 變 1,1 變 0), 相當于邏輯非/異或 1
to_string() : 返回轉換成的字符串表達
to_ulong() : 返回轉換成的 unsigned long 表達 ( long 在 NT 及 32 位 POSIX 系統下與 int 一樣,在 64 位 POSIX 下與 long long 一樣)
to_ullong() C++11, 返回轉換成的 unsigned long long 表達
這些 vector<bool> 基本都沒有

?

作用?
一般來講,我們可以用 bitset 優化一些可行性 DP, 或者線篩素數 ( notprime 這種 bool 數組可以用 bitset 開到 之類的)

?

它最主要的作用還是壓掉了內存帶來的時間優化, 的常數優化已經可以是復雜度級別的優化了,比如一個 的 算法, 顯然很卡,在常數大一點的情況下必然卡不過去,O(松)不能算!, 這時候如果我們某一維除以 32, 則可以比較保險的過了這道題

?

其實 bitset 不光是一個容器,更是一種思想,我們可以通過手寫的方式,來把 long long 什么的壓成每 bit 表示一個信息,用 STL 的原因更多是因為它的運算符方便

作者:Chicago
鏈接:https://www.acwing.com/solution/acwing/content/899/
來源:AcWing

#include <bits/stdc++.h>using namespace std;typedef long long ll; const int INF = 0x3f3f3f3f; const int MAXN = 3e4 + 100; const int MAXM = 3e3 + 10; const double eps = 1e-5;template < typename T > inline void read(T &x) {x = 0; T ff = 1, ch = getchar();while(!isdigit(ch)) {if(ch == '-') ff = -1;ch = getchar();}while(isdigit(ch)) {x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar(); }x *= ff; }template < typename T > inline void write(T x) {if(x < 0) putchar('-'), x = -x;if(x > 9) write(x / 10);putchar(x % 10 + '0'); }int n, m, top, in[MAXN], b[MAXN]; bitset < MAXN > a[MAXN]; int lin[MAXN], tot = 0; struct edge {int y, next; }e[MAXN];inline void add(int xx, int yy) {e[++tot].y = yy;e[tot].next = lin[xx];lin[xx] = tot; }void topsort() {queue < int > q;for(int i = 1; i <= n; ++i) {if(in[i] == 0) q.push(i);} while(!q.empty()) {int x = q.front(); q.pop();b[++top] = x;for(int i = lin[x], y; i; i = e[i].next) {if(--in[y = e[i].y] == 0) q.push(y); } }}int main() {read(n); read(m);for(int i = 1; i <= m; ++i) {int x, y;read(x); read(y);add(x, y);in[y]++;} topsort();for(int i = top; i >= 1; --i) {int x = b[i];a[x][x] = 1;for(int j = lin[x]; j; j = e[j].next) {a[x] |= a[e[j].y]; }} for(int i = 1; i <= n; ++i) {cout << a[i].count() << endl;}return 0; }

?

轉載于:https://www.cnblogs.com/AK-ls/p/11106434.html

總結

以上是生活随笔為你收集整理的AcWing 164. 可达性统计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。