n
nn個點的一顆樹,合法路徑定義為一條路徑上每個點的編號相差大於k
kk。求合法路徑數
首先我們可以求不合法的路徑數,這樣我們就有了k∗n
k*nk∗
n個不合法(即不能在同乙個路徑上)的點對。
然後這題就和之前一題jzoj6276一樣了
大概就是用矩形表示不合法的路徑,之後用掃麵線求矩形的面積並即可。
#pragma gcc optimize(2)
%:pragma gcc optimize(3
)%:pragma gcc optimize
("ofast")%
:pragma gcc optimize
("inline"
)#include
#include
#include
#include
using
namespace std;
const
int n=
3e5+10;
struct nodea[n*2]
;struct linel[n*40]
;bool
operator
<
(line x,line y)
int n,k,tot,cnt,num;
int rfn[n]
,ed[n]
,f[n][21
],dep[n]
;int w[n*4]
,mark[n*4]
,ls[n]
;long
long ans;
__attribute__((
optimize
("o3"))
)inline
intread()
while
(isdigit
(c)) x=
(x<<1)
+(x<<3)
+c-48
,c=getchar()
;return x*f;
}void
addl
(int x,
int y)
void
dfs(
int x,
int fa)
ed[x]
=cnt;
return;}
intlca
(int x,
int y)
void
addc
(int x1,
int x2,
int y1,
int y2)
; l[
++num]
=(line);}
void
ban(
int x,
int y)
else
addc
(rfn[x]
,ed[x]
,rfn[y]
,ed[y]);
return;}
void
change
(int x,
int l,
int r,
int l,
int r,
int val)
int mid=
(l+r)
>>1;
if(r<=mid)
change
(x*2
,l,mid,l,r,val)
;else
if(l>mid)
change
(x*2+1
,mid+
1,r,l,r,val)
;else
change
(x*2
,l,mid,l,mid,val)
,change
(x*2+1
,mid+
1,r,mid+
1,r,val);if
(mark[x]
)w[x]
=r-l+1;
else w[x]
=w[x*2]
+w[x*2+
1];return;}
intmain()
dfs(1,
1);for
(int i=
1;i<=
20;i++
)for
(int j=
1;j<=n;j++
) f[j]
[i]=f[f[j]
[i-1]]
[i-1];
for(
int i=
1;i<=n;i++
)for
(int j=i+
1;j<=
min(i+k,n)
;j++
)ban
(i,j)
;sort
(l+1
,l+1
+num)
;int z=1;
for(
int i=
1;i<=n;i++
)printf
("%lld"
,1ll
*n*(n-1)
/2-ans+n)
;}
掃瞄線,線段樹 nssl 1459 空間複雜度
由於 k leq 10 所以考慮用總方案減去經過兩個差的絕對值 leq k 的點的路徑數 分類討論一下發現要處理祖先關係和其它關係兩種情況,考慮怎麼去重,可以將這些答案看作乙個個矩形,然後就是要求矩形的面積並,用掃瞄線 線段樹解決 include include include include de...
SSLOJ1459 空間簡單度
考慮用總方案數減去空間簡單度不超過 k 的方案數。發現 k 很小,可以列舉所有點 i 那麼對於乙個 i j leq k 的點 j 發現這個點對貢獻了路徑 i to j 兩端 點的數量之積。但是直接計算容易重複,發現每次將是 dfs 序不超過 3 個區間的點的乘積,那麼求出每個點字數點的 dfs 序區...
簡單介紹 空間複雜度
是什麼?指執行某個演算法所需要的記憶體空間 由於現在科技的發展我們完全可以用空間去換取時間 例 要判斷某年是不是閏年?花點心思來寫乙個演算法,每給乙個年份,就可以通過這個演算法計算得到是否是閏年的結果。事先建立乙個有2050個元素的陣列,然後把所有的年份按下錶的數字對應,如果是閏年,則此陣列元素的值...