[CF538F] A Heap of Heaps - 整除分塊,數學,樹
阿新 • • 發佈:2020-09-09
Description
有一個小根堆,這個堆變成了一個 \(k\) 叉堆(形式轉化,逐層排布),但這樣不一定是合法的(即有若干個節點小於它的父親)。問現在這個堆有多少不合法的元素。對所有 \(k\) 輸出結果。
Solution
\(x\) 號點在 \(k\) 叉樹上的父親是 \([\frac {x-2} {k}]+1\)
列舉兒子來計算答案,顯然可以整除分塊,用差分計算答案,複雜度為 \(O(n \sqrt n)\)
#include <bits/stdc++.h> using namespace std; #define int long long const int N = 1000005; int a[N],n,ans[N]; void modify(int l,int r) { ans[l]++; ans[r+1]--; } void solve() { for(int i=1;i<=n;i++) ans[i]+=ans[i-1]; } signed main() { ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=2;i<=n;i++) { int l=1,r=1; while(l<=(i-2)) { r=(i-2)/((i-2)/l); int p=(i-2)/l+1; if(a[i]<a[p]) { modify(l,r); } l=r+1; } if(a[1]>a[i]) ans[l]++; } solve(); for(int i=1;i<n;i++) cout<<ans[i]<<" "; }