傳送門
長鏈剖分的板子(又是亂搞優化暴力)
對於每乙個點,我們定義它深度最深的子節點為它的重兒子(為什麼不叫長兒子……),他們之間的連邊為重邊
然後長鏈剖分有幾個性質
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的二...