題目描述:
給一棵n個節點的帶點權的樹,求: ∑x
=1n∑
y=x+
1n∑d
is(x
,y)+
1k=1
(路徑x
−y上前
k大點的
點權和)
∑ x=
1n∑y
=x+1
n∑k=
1dis
(x,y
)+1(
路徑x−
y上前k
大點的點
權和
)解題思路:
乙個節點的權值會被計算所有鏈上點權小等於它的點數次。
我們把點按權值從小到大排序後依次插入,對於插入的點
u u
,分情況討論之前插入的乙個點
v' role="presentation">vv對
u u
的次數貢獻(v在
子樹內或
v是u的
祖先' role="presentation">v在子
樹內或v
是u的祖
先v在子
樹內或v
是u的祖
先),用樹狀陣列維護即可,具體可以自己畫圖推推再結合**。
#include
#define ll long long
using namespace std;
int getint()
const
int n=100005,mod=1e9+7;
int n,ans;
struct nodea[n];
inline bool
operator
< (const node &a,const node &b)
inline ll query(int i)
inline void add(int l,int r,int v)
inline ll query(int l,int r)
}bit1,bit2,bit3;
void add(int x,int y)
void dfs(int u)
out[u]=idx;
}int calc(int u,int w)
else
}bit1.add(in[u],size[u]);
bit2.add(in[u],out[u],size[u]),bit3.add(in[u],out[u],1);
for(int e=first[u];e;e=nxt[e])
return res*w%mod;
}int main()
; dfs(1),sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
ans=(ans+calc(a[i].id,a[i].val))%mod;
cout<'\n';
return
0;}
BJ模擬(1) D2T3 鏈上求和
鏈上求和 題目背景 分析 這個題,我真的很想呵呵,當時聽滿分神犇講了一次,然後學長講了一次,然後默默的自己看了 n次,然後在給別人講了兩次,才終於算是基本懂了 現在讓我寫,恐怕還是只有呵呵 我們先一步步進行考慮,首先對於一條鏈上的某乙個點,他在這一條鏈上的統計次數,是這條鏈上比它的權值小的點的個數加...
D 區間求和 數學 樹狀陣列
題意 求 sum n sum sum n 區間前k大值和 比賽時因為被b卡了沒有深入想這道題 結果b沒做出來後面的題也沒做 化一下式子 begin sum n sum n sum r a k cdot 1 sum r a i a k 考慮乙個數的貢獻 sum n sum n a k cdot a i...
NOIP模擬 相交(樹鏈剖分 樹狀陣列維護)
我已經無力爆粗了。md這c 怎麼能在編譯了 執行了以後,最後發現居然是之前的版本?喵喵喵?考慮兩條路徑相交,那麼其中一條的lca一定在另一條路徑上。所以開兩個樹狀陣列維護之前路徑的資訊和之前路徑的lca的位置。統計一下,然後更新,再做下一條路徑即可。includeusing namespace st...