對於 50% 的資料:直接模擬
對於另外10%的資料:因為地圖是一條鏈,顯然 yousiki 會消滅所有距離他為偶數條邊的祖
先。對於100%的資料:我們先把整個樹 dfs 一遍,遇到乙個點就把這個點記錄到乙個陣列後邊,
即求出了樹的尤拉序,顯然如果不考慮迴圈的話,guard是在這個序列上每次往後走乙個,起
始位置就是第i個點第一次出現的位置。
而顯然 yousiki 只可能與他的所有祖先相遇,所以我們把他所有祖先的起始位置標記出來。
假設 yousiki 現在走到了 x 點,過了 t 秒,那麼我們在這個序列上遍歷 x 出現的所有位置,
並檢視這個位置往前 t 個是否為 x 的祖先,如果是,把那個祖先標為1,表示已被消滅。
複雜度 。
#include #include #define fin stdin
#define fout stdout
//file *fin = fopen("in.txt", "r");
//file *fout = fopen("out1.txt", "w");
inline int nextchar()
inline int nextint()
const int mxn = 5000015;
const int mxm = 20000015;
int n, s, tt;
int hd[mxn];
int nt[mxn];
int to[mxn];
inline void addedge(int u, int v)
int dfn[mxm];
int dep[mxn];
int mrk[mxn];
int tim[mxn];
int vis[mxn];
int fst[mxn];
int tmp;
int tot;
int ans;
bool dfs(int u)
if (mrk[u])tim[u] = tmp++;
return mrk[u];
}signed main()
s = nextint();
tmp = tot = 0, dfs(1);
memset(vis, 0, sizeof(int) * (n + 5)), ans = 0;
for (int i = 1, u, v; i <= tot; ++i)
if (mrk[u = dfn[i]] && i > tim[u] && fst[i - tim[u]])
if (mrk[v = dfn[i - tim[u]]] && dep[v] <= dep[u])
ans += (vis[v] == 0), vis[v] = 1;
fprintf(fout, "%d\n", ans); }
fclose(fin);
fclose(fout);
return 0;
}
天天愛跑步
一道 樹上差分 lca 桶的題 說實話,這道題放在d1t2就是非常不合理的。然而ccf就是放了,並且還是能依靠csp撈錢,你也必須交錢參加比賽。這個社會是多麼的不公啊!閒扯結束 顯然如果對每條路徑都進行一次處理,複雜度不對。考慮對路徑進行一次預處理,然後進行統一的計算答案。我們發現當一條路徑對某乙個...
天天愛跑步
終於拿下noip最難一題 看別人的題解看不懂 於是準備寫一篇更通俗易懂雜亂無章的題解 樹上差分 線段樹 桶 lca 將每條路徑在lca處切成上公升路徑和下降路徑 會發現對於x號觀察員若觀察到玩家i 則必有dep i w x depx 或dep i 2 dep lca w x depx 我們用桶標記 ...
天天愛跑步
暴力程式 25pts 複雜度 o n 2 includeusing namespace std const int maxn 3e5 10 int n,m,ans maxn inline int read while c 0 c 9 return x f int beg maxn nex maxn ...