NOIP2016提高Day1 天天愛跑步

2021-08-29 23:15:41 字數 1450 閱讀 9502

魔鬼題面

lca + 樹上差分。對於一次詢問u到v,我們可以拆成兩段,一段為u到lca,一段為lca到v。

先考慮u到lca,即從下到上的情況。對於在i點的觀察員,只有深度在depth[i] + w[i]的點才可能對i點有貢獻,這個貢獻在lca點結束。那麼利用差分思想,我們在depth[i] + w[i]的點打上標記,在lca處減去標記,則u到lca這一段就有了1的貢獻。當我們dfs到乙個節點x時,需要求的答案是x子樹中節點的貢獻,即回溯完成後標記陣列的變化量,我們在遞迴前儲存一下初始值,去子樹逛一圈後得到新的值,用新的值減去舊的就是變化量了。

那麼lca到v的情況與上述情況相反,即從上往下,但思想是一樣的,因為depth[i] - w[i]可能為負數,我們需要加上乙個相同的偏移量防止程式執行錯誤。

#include#include#include#include#include#include#include#include#include#define maxa 1000005

using namespace std;

int head[maxa],cnt;

struct rx_graph edge[maxa];

struct rx ;

vectorgx[maxa];

rx make(int a,int b,int c)

void add(int u,int v)

int depth[maxa],f[maxa][20],py = 30000;

int lca(int x,int y)

return f[x][0];

}void init(int x,int last)

}void chafen(int u,int v)

int n,m,u,v,checktime[maxa],start,target,cnt1[maxa],cnt2[maxa],ans[maxa];

void dfs(int x,int last)

for(int i=head[x];i;i=edge[i].next)

ans[x] = cnt1[checktime[x] + depth[x]] + cnt2[depth[x] - checktime[x] + py] - now;

}int main()

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

scanf("%d",&checktime[i]);

depth[1] = 1;

init(1,0);

for(int j=1;j<=18;j++)

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

f[i][j] = f[f[i][j-1]][j-1];

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

dfs(1,0);

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

printf("%d ",ans[i]);

}

NOIP2016提高組day1 換教室

對於剛上大學的牛牛來說,他面臨的第乙個問題是如何根據實際情況申請合適的 課程。在可以選擇的課程中,有 2n 節課程安排在 n 個時間段上。在第 i 1 i n 個 時間段上,兩節內容相同的課程同時在不同的地點進行,其中,牛牛預先被安排在教室 ci 上課,而另一節課程在教室 di 進行。在不提交任何申...

天天愛跑步(NOIP2016提高組Day1T2)

題目描述 小c同學認為跑步非常有趣,於是決定製作一款叫做 天天愛跑步 的遊戲。天天愛跑步 是乙個養成類遊戲,需要玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一一棵包含n個結點和n 1條邊的樹,每條邊連線兩個結點,且任意兩個結點存在一條路徑互相可達。樹上結點編號為從1到n的連續正整數。現在有...

NOIP2016提高組day2 蚯蚓

本題中,我們將用符號 lcj 表示對 c 向下取整,例如 l3.0j l3.1j l3.9j 3 蛐蛐國最近蚯蚓成災了!隔壁跳蚤國的跳蚤也拿蚯蚓們沒辦法,蛐蛐國王只好去 請神刀手來幫他們消滅蚯蚓。蛐蛐國裡現在共有 n 只蚯蚓 n 為正整數 每只蚯蚓擁有長度,我們設第 i 只匠 蚓的長度為 ai i ...