題目描述
小c同學認為跑步非常有趣,於是決定製作一款叫做《天天愛跑步》的遊戲。«天天愛跑步»是乙個養成類遊戲,需要玩家每天按時上線,完成打卡任務。
這個遊戲的地圖可以看作一一棵包含 個結點和 條邊的樹, 每條邊連線兩個結點,且任意兩個結點存在一條路徑互相可達。樹上結點編號為從到的連續正整數。
現在有個玩家,第個玩家的起點為 ,終點為 。每天打卡任務開始時,所有玩家在第秒同時從自己的起點出發, 以每秒跑一條邊的速度, 不間斷地沿著最短路徑向著自己的終點跑去, 跑到終點後該玩家就算完成了打卡任務。 (由於地圖是一棵樹, 所以每個人的路徑是唯一的)
小c想知道遊戲的活躍度, 所以在每個結點上都放置了乙個觀察員。 在結點的觀察員會選擇在第秒觀察玩家, 乙個玩家能被這個觀察員觀察到當且僅當該玩家在第秒也理到達了結點 。 小c想知道每個觀察員會觀察到多少人?
注意: 我們認為乙個玩家到達自己的終點後該玩家就會結束遊戲, 他不能等待一 段時間後再被觀察員觀察到。 即對於把結點作為終點的玩家: 若他在第秒重到達終點,則在結點的觀察員不能觀察到該玩家;若他正好在第秒到達終點,則在結點的觀察員可以觀察到這個玩家。
輸入格式:
第一行有兩個整數和 。其中代表樹的結點數量, 同時也是觀察員的數量, 代表玩家的數量。
接下來 行每行兩個整數和 ,表示結點 到結點 有一條邊。
接下來一行 個整數,其中第個整數為 ,
表示結點出現觀察員的時間。
接下來 行,每行兩個整數,和,表示乙個玩家的起點和終點。
對於所有的資料,保證 。
輸出格式:
輸出1行 個整數,第個整數表示結點的觀察員可以觀察到多少人。
輸入樣例#1:
6 32 3
1 2
1 4
4 5
4 6
0 2 5 1 2 3
1 5
1 3
2 6
輸出樣例#1:
2 0 0 1 1 1
輸入樣例#2:
5 3
1 2
2 3
2 4
1 5
0 1 0 3 0
3 1
1 45 5
輸出樣例#2:
1 2 1 0 1
說明
【樣例1說明】
對於1號點,,故只有起點為1號點的玩家才會被觀察到,所以玩家1和玩家2被觀察到,共有2人被觀察到。
對於2號點,沒有玩家在第2秒時在此結點,共0人被觀察到。
對於3號點,沒有玩家在第5秒時在此結點,共0人被觀察到。
對於4號點,玩家1被觀察到,共1人被觀察到。
對於5號點,玩家1被觀察到,共1人被觀察到。
對於6號點,玩家3被觀察到,共1人被觀察到。
【提示】
如果你的程式需要用到較大的棧空問 (這通常意味著需要較深層數的遞迴), 請務必仔細閱讀選手日錄下的文字當rumung:/stact.p″, 以了解在最終評測時棧空問的限制與在當前工作環境下調整棧空問限制的方法。
在最終評測時,呼叫棧占用的空間大小不會有單獨的限制,但在我們的工作
環境中缺省會有 8 mb 的限制。 這可能會引起函式呼叫層數較多時,
程式發生
棧溢位崩潰。
我們可以使用一些方法修改呼叫棧的大小限制。 例如, 在終端中輸入下列命
令 ulimit -s 1048576
此命令的意義是,將呼叫棧的大小限制修改為 1 gb。
例如,在選手目錄建立如下
sample.cpp 或 sample.pas
將上述源**編譯為可執行檔案
sample 後,可以在終端中執行如下命令運
行該程式
./sample
如果在沒有使用命令「
ulimit -s 1048576」的情況下執行該程式, sample
會因為棧溢位而崩潰; 如果使用了上述命令後執行該程式,該程式則不會崩潰。
特別地, 當你開啟多個終端時,
它們並不會共享該命令, 你需要分別對它們
執行該命令。
請注意, 呼叫棧占用的空間會計入總空間占用中,
和程式其他部分占用的內
存共同受到記憶體限制。
用lca演算法,找到最近公共祖先,然後可以查出s到t的最短路徑(也可以用圖上最短路徑做法,但是畢竟這是在樹上,lca顯得更合適省時),於是可以找出路上每個點是在哪個時刻經過的,如果這個時刻與觀察員出現的時刻相同,則觀察員能觀察到的數量就+1
(鬱悶ing,第一次打lca,幾乎用了乙個上午的時間,卻因為超時只得了25分。。)
你還要我怎樣,要怎樣。。。
//怎麼才能不超時!!
#include#include
#include
#include
using
namespace
std;
vector
e[300000
];int dep[300000],f[300000][25
];int
n,m,lca,num;
int point[300000
];int ans[300000
];int cmp[300000
];int
qread()
while(ch<='
9'&&ch>='0')
return x*j;
}void find_deep(int pos,int
pre)
}}void
yuchuli()
}}void show(int lca,int
ed)void dic(int start,int
end)
else
lca=f[a][0
]; }
int st,ed;st=start,ed=end;
memset(cmp,
0,sizeof
(cmp));
num=0
; cmp[++num]=st;
while(st!=lca)
show(lca,ed);
//for(int i=1;i<=num;i++)cout
if(point[cmp[i]]==i-1)ans[cmp[i]]++;
}int
main()
for(int i=1;i<=n;i++)cin>>point[i];
dep[
1]=1
; find_deep(
1,-1
); yuchuli();
//for(int i=1;i<=n;i++)cout
for(int i=1;i<=n;i++)
cout
cout
<
}
Noip2016day1 天天愛跑步running
小c同學認為跑步非常有趣,於是決定製作一款叫做 天天愛跑步 的遊戲。天天愛跑步 是乙個養成類遊戲,需要玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一一棵包含 個結點和 條邊的樹,每條邊連線兩個結點,且任意兩個結點存在一條路徑互相可達。樹上結點編號為從到的連續正整數。現在有個玩家,第個玩家的...
NOIP2016 DAY1T2 天天愛跑步
描述 小c同學認為跑步非常有趣,於是決定製作一款叫做 天天愛跑步 的遊戲。天天愛跑步 是乙個養成類遊戲,需要玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一棵包含n個結點和n 1條邊的樹,每條邊連線兩個結點,且任意兩個結點存在一條路徑互相可達。樹上結點編號為從1到n的連續正整數。現在有m個玩...
NOIP2016提高Day1 天天愛跑步
魔鬼題面 lca 樹上差分。對於一次詢問u到v,我們可以拆成兩段,一段為u到lca,一段為lca到v。先考慮u到lca,即從下到上的情況。對於在i點的觀察員,只有深度在depth i w i 的點才可能對i點有貢獻,這個貢獻在lca點結束。那麼利用差分思想,我們在depth i w i 的點打上標記...