vijos lxhgww的奇思妙想(長鏈剖分)

2022-02-27 20:28:29 字數 1508 閱讀 1840

傳送門

長鏈剖分的板子(又是亂搞優化暴力)

對於每乙個點,我們定義它深度最深的子節點為它的重兒子(為什麼不叫長兒子……),他們之間的連邊為重邊

然後長鏈剖分有幾個性質

1.總鏈長為$o(n)$

2.乙個節點的$k$級祖先的子樹深度必定大於等於當前節點的子樹深度

以上兩點稍微yy一下就能發現是對的

然後回到這道題。我們設$len[u]$為這一條長鏈的長度,對於每乙個長鏈的頂點,我們維護它的1到$len[u]$級兒子以及1到$len[u]$級祖先

同時預處理找祖先的倍增陣列,並預處理出1到$n$的每乙個數字的二進位制最高位即$highbit$

那麼對於每乙個詢問$(u,k)$,我們設$r=highbit(k)$,那麼我們用預處理的倍增陣列讓$u$跳到它的$r$級祖先$v$處

因為$k-rk-r$,那麼$v$所在的長鏈預處理的表一定已經包含了$u$的$k$級祖先

時間複雜度為$o(nlogn+m)$,預處理$o(nlogn)$,每一次回答$o(1)$

1

//minamoto

2 #include3 #include4 #include5

using

namespace

std;

6#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?eof:*p1++)

7char buf[1

<<21],*p1=buf,*p2=buf;

8int

read()

18char sr[1

<<21],z[20];int c=-1

,z;19 inline void ot()

20void print(int

x)25

const

int n=3e5+5;26

int head[n],next[n<<1],ver[n<<1

],tot;

27 inline void add(int u,int

v)30

int n,md[n],dep[n],fa[n][21

],son[n],top[n],len[n],b[n];

31 vectoru[n],d[n];

32void dfs(int u,int

f)43}44

}45void dfs2(int u,int

t)52}53

void

init()

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

60if(i==top[i])64}

65int query(int u,int

k)73

intmain()

80 dfs(1,0),dfs2(1,1

),init();

81int lastans=0,q=read();

82while(q--)

86return ot(),0

;87 }

奇思妙想的演算法隨筆

有n個數,現在要求兩兩之間差值的和,要求盡量低的複雜度。思路a 直接列舉,o n 2 的複雜度 int ans 0 for i 1 i n i 思路b 我們將整個陣列進行由小到大的排序,然後使用公式法。假設排序完之後的陣列狀態為 此時我們關注按照不同起點分割答案,那麼對於每乙個起點 我們將他以段的形...

asp 奇思妙想 困惑

這幾天為學校做了幾個 發現乙個問題,有一些資料庫 大部分是access的,還有一些msql的 在設計時出現了問題,造成了資料庫裡面的很多內容是冗餘的,所以需要對資料庫進行清理。所以就開始寫了乙個asp的檔案cleandata.asp 見後文 關鍵問題在於資料庫的問題,我本來在我的機器上有測試的資料,...

奇思妙想位運算

本篇旨在記錄 奇思妙想 的位運算。int c 10 intcount c 0 0 1 while c c c 1 解析 c 1 會導致c最末尾的1 因為借位變為0,而此前最末尾的1後面必然全是0 或者1為個位 所以當c c 1 時,就相當於消去c中最末尾的乙個1。如6的二進位制是0110,6 1的二...