給出一棵n個節點以1為根的樹,和m次操作。
每次操作把x個人扔進這棵樹。
每個人會選擇當前節點中乙個沒有人且編號最大的節點走過去。
問最後乙個人停在哪個節點。
或者把x這個節點的人刪除,把它上面的所有人往下移一格,問移動了多少人。
n,m<=10^5
你有木有覺得這個走的方法很像dfs序的遍歷?
那麼我們可以構造出這個特殊的dfs序,不過每次我們選擇編號大的先走。
這東西你可以用set/vector/map/queue等等黑科技來做。
(p黨傷不起就去轉c吧)
這樣子就可以保證這個序列從後往前就是我們要插入的順序了。
於是我們可以給每個點乙個優先順序,然後把它們按優先順序排序。
同時要茲瓷插入刪除。。
辣麼用set/queue/heap就好辣
p黨:卒
操作二就倍增往上跳到最上面乙個有人的節點。
因為不可能乙個節點沒人但他的父輩有人。
然後就解決啦(黑科技大全紀念)
#include
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define n 100005
using
namespace
std;
typedef
set :: iterator its;
set s[n];
int dfn[n],fa[n][17],d[n],tot,n,m,x,y,z;
bool bz[n],in[n];
struct note while (it!=s[x].begin());
note z;z.id=x;
if (!pd) q.insert(z),in[x]=1;
}int jump(int x)
int main()
if (i==x) printf("%d\n",v.id);
}} else
}}
NOIP2016提高A組五校聯考1 道路規劃
我們考慮,當現在有乙個合法的集合時,如何往裡面增加乙個點,使這個集合仍然合法。假設現在有乙個合法的集合,那麼當我們加入乙個點,它的道路穿過來整個集合,那麼 然後搞一遍最長下降子串行就可以了。include include include include include const int maxlo...
NOIP2016提高A組五校聯考1 挖金礦
剛看到這題時,還在想怎麼貪心,然後很快的打完之後發現貪心是錯的。然後仔細的看了看範圍,哈哈,這不是二分嗎。二分出乙個mid,然後在所有行裡面用mid j 字首和然後找乙個最大值。最後把這些最大值加起來,判斷一下就好了。include include include include include i...
NOIP2016提高A組五校聯考1 挖金礦
答案,保留4位小數 4 3 4 3 3 5 1 6 2 6 1 3 2 9 4.4286 n m 100000 很簡單的一道題 設sum i j 表示第i列向下挖j行的字首和 假設第i列挖h i 行 設二分的答案是m,答案如果合法,那麼 n i 1s um i h i ni 1 h i m 移項 i...