BZOJ4448 Scoi2015 情報傳遞

2022-03-29 16:43:09 字數 2699 閱讀 3446

bzoj4448: [scoi2015]情報傳遞

奈特公司是乙個巨大的情報公司,它有著龐大的情報網路。情報網路中共有n名情報員。

每名情報員口j-能有若t名(可能沒有)下線,除1名大頭日外其餘n-1名情報員有且僅有1名上線。

奈特公司紀律森嚴,每名情報員只能與自己的上、下線聯絡,同時,情報網路中仟意兩名情報員一定能夠通過情報網路傳遞情報。

奈特公司每天會派發以下兩種任務中的乙個任務:

1.蒐集情報:指派t號情報員蒐集情報

2.傳遞情報:將一條情報從x號情報員傳遞給y號情報員

情報員最初處於潛伏階段,他們是相對安全的,我們認為此時所有情報員的危險值為0;

-旦某個情報員開始蒐集情報,他的危險值就會持續增加,每天增加1點危險值(開始蒐集情報的當天危險值仍為0,第2天危險值為1,第3天危險值為2,以此類推)。

傳遞情報並不會使情報員的危險值增加。

為了保證傳遞情報的過程相對安全,每條情報都有乙個風險控制值c。

餘特公司認為,參與傳遞這條情報的所有情報員中,危險值大於c的情報員將對該條情報構成威脅。

現在,奈特公司希望知道,對於每個傳遞情報任務,參與傳遞的情報員有多少個,其中對該條情報構成威脅的情報員有多少個。

第1行包含1個正整數n,表示情報員個數。

笫2行包含n個非負整數,其中第i個整數pi表示i號情報員上線的編號。特別地,若pi=0,表示i號情報員是大頭目。

第3行包含1個正整數q,表示奈特公司將派發q個任務(每天乙個)。

隨後q行,依次描述q個任務。

每行首先有1個正整數k。

若k=1,表示任務是傳遞情報,隨後有3個正整數xi、yi、ci,依次表示傳遞情報的起點、終點和風險控制值;

若k=2,表示任務是蒐集情報,隨後有1個正整數ti,表示蒐集情報的情報員編號。

對於每個傳遞情報任務輸出一行,應包含兩個整數,分別是參與傳遞情報的情報員個數和對該條情報構成威脅的情報員個數。

輸出的行數應等於傳遞情報任務的個數,每行僅包含兩個整數,用乙個空格隔開。輸出不應包含多餘的空行和空格。

70 1 1 2 2 3 3

61 4 7 0

2 12 4

2 71 4 7 1

1 4 7 3

5 05 2

5 1對於3個傳遞情報任務,都是經過5名情報員,分別是4號、2號、1號、3號和7號。

其中,對於第1任務,所有情報員(危險值為0)都不對情報構成威脅;

對於第2個任務,有2名情報員對情報構成威脅,分別是1號情報員(危險值為3)和4號情報員(危險值為2),7號情報員(危險值為1)並不構成威脅;

對於第3個任務,只有1名情報員對情報構成威脅。

n< = 2×10^5,q< = 2×105,0< pi,c!< = n, 1< = ti,xi,yi< = n

額,其實還是蠻好想的。

樹上問題就直接套乙個樹鏈剖分嘛。

題目要求:鏈上所有威脅值大於$x$的點的個數。

轉化一下,就是:鏈上開始蒐集的日子小於$i-x-1$的點的個數,$i$為當前的時間。

顯然主席樹啊!

然後就變成了樹剖套主席樹。

複雜度$o(n\log_2^2n)$。

但是!$n\leq 2\times 10^5$!

這。。。好像會$tle$吧。。。

哦,時限$2s$。。。

但是我們還有更快的演算法!

樹上主席樹!

簡單的來說就是如果我們要查詢$(u,v)$,那麼我們實際查詢樹上字首和(假設字首和陣列為$sum[i]$)的就是:

$$sum[u]+sum[v]-sum[lca(u,v)]-sum[fa[lca(u,v)]]$$

$fa[i]$表示$i$的父親。

然後把那個字首和換成主席樹即可。

複雜度$o(n\log_2n)$。

於是我們的樹剖出了求$lca$之外好像沒有啥作用。。。

注:然後我用實踐證明了什麼是**$10min$,除錯一下午。。。

我竟然把從來沒有敲錯的樹鏈剖分板子敲錯了。。。

然後。。。可想而知。。。$tle$了一下午。。。

附**:

#include#include#include#define maxn 200010

using namespace std;

int n,m,c=1;

int head[maxn],deep[maxn],son[maxn],size[maxn],fa[maxn],top[maxn];

int val[maxn],root[maxn];

struct treea[maxn];

struct questionque[maxn];

inline int read()

return date;

}namespace cta[maxn*20];

inline void buildtree()

void insert(int k,int l,int r,int &rt)

int query(int u,int v,int fa,int fafa,int l,int r,int lside,int rside)

void work()

}void init()

m=read();

for(int i=1;i<=m;i++)

else

} deep[root]=1;

dfs1(root);

dfs2(root,root);

}int main()

bzoj 4448 Scoi2015 情報傳遞

description 奈特公司是乙個巨大的情報公司,它有著龐大的情報網路。情報網路中共有n名情報員。每名情報員口j 能有 若t名 可能沒有 下線,除1名大頭日外其餘n 1名情報員有且僅有1名上線。奈特公司紀律森嚴,每 名情報員只能與自己的上 下線聯絡,同時,情報網路中仟意兩名情報員一定能夠通過情報...

BZOJ 4448 Scoi2015 情報傳遞

bzoj 4448 scoi2015 情報傳遞 主席樹 奈特公司是乙個巨大的情報公司,它有著龐大的情報網路。情報網路中共有n名情報員。每名情報員口j 能有 若t名 可能沒有 下線,除1名大頭日外其餘n 1名情報員有且僅有1名上線。奈特公司紀律森嚴,每 名情報員只能與自己的上 下線聯絡,同時,情報網路...

BZOJ4448 SCOI2015 情報傳遞

傳送門 題目大意 給定一棵樹,支援兩種操作 將乙個點染黑,詢問路徑上在 k 步操作前就已經被染黑的點的數量。題解將染黑看做給乙個點賦其操作編號點權,每次詢問路徑上點權小於一定值的數量。這樣會有乙個性質,由於 k 0 所以我們完全可以在查詢之前將所有點權賦上。所以只需要離線然後查詢就好了,可以在樹上利...