日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

hdu 4918

發(fā)布時(shí)間:2025/5/22 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu 4918 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

第一道樹(shù)的點(diǎn)分治。

感謝:

http://blog.csdn.net/u013368721/article/details/40887575

?

首先,找出原圖的重心(最大子樹(shù)大小最小的點(diǎn)(如果作為根)),去掉它后原圖就分成了若干的森林,再在對(duì)應(yīng)的森林中找出重心,遞歸這個(gè)過(guò)程(只有一個(gè)點(diǎn)時(shí)返回)。

這樣,我們就可以根據(jù)重心的所屬關(guān)系,建立出一棵樹(shù),顯然原圖的重心就是這顆樹(shù)的重心,每個(gè)重心對(duì)應(yīng)一些點(diǎn)(就是去掉該重心前,該重心聯(lián)通塊中的所有點(diǎn))。

容易看出,因?yàn)槊看芜x的是重心,所以樹(shù)每次至少會(huì)分成兩塊(最壞情況),考慮我們根據(jù)重心所屬關(guān)系建立出的樹(shù),最多有O(logn)層,每層找重心總的復(fù)雜度是O(n)(因?yàn)槊繉又匦膶?duì)應(yīng)的點(diǎn)是O(n)級(jí)別的),所以建立這個(gè)關(guān)系是O(nlogn)的復(fù)雜度。

應(yīng)前輩的稱呼,我們就叫建立出的這顆很多重心的樹(shù)為重心樹(shù)。

對(duì)于這道題,我們可以給重心樹(shù)的每個(gè)節(jié)點(diǎn)建立一個(gè)樹(shù)狀數(shù)組,樹(shù)狀數(shù)組下標(biāo)為到重心的距離,值為點(diǎn)的權(quán)值,將重心對(duì)應(yīng)的點(diǎn)都放到這個(gè)樹(shù)狀數(shù)組中(因?yàn)樽畲缶嚯x就是該重心對(duì)應(yīng)的點(diǎn)數(shù)-1,所以樹(shù)狀數(shù)組的大小就設(shè)成該重心對(duì)應(yīng)的點(diǎn)數(shù)),因?yàn)橐粚訉?duì)應(yīng)的所有重心對(duì)應(yīng)的點(diǎn)數(shù)最多為O(n),所以總共占用的空間為O(nlogn)。然后還要根據(jù)這個(gè)重心的不同子重心分開(kāi)記錄一下這個(gè)東西,用于去重。

?

1 #include <cstdio> 2 #include <vector> 3 #include <map> 4 #define N 100010 5 using namespace std; 6 7 struct Stat { 8 int r, d, s; 9 Stat( int r, int d, int s ):r(r),d(d),s(s){} 10 }; 11 struct Bit { 12 int n; 13 vector<int> vv; 14 void init( int n ) { 15 this->n = n; 16 vv.resize( n+1 ); 17 for( int t=1; t<=n; t++ ) vv[t] = 0; 18 } 19 void modify( int pos, int delta ) { 20 pos++; 21 for( int i=pos; i<=n; i+=i&-i ) 22 vv[i]+=delta; 23 } 24 int query( int pos ) { 25 int rt = 0; 26 pos++; 27 if( pos>n ) pos=n; 28 for( int i=pos; i; i-=i&-i ) 29 rt += vv[i]; 30 return rt; 31 } 32 }; 33 34 int n, m; 35 vector<int> g[N]; 36 vector<Stat> st[N]; 37 map<int,Bit > bit[N]; 38 int ww[N]; 39 int vis[N], siz[N], anc[N], bac[N], dis[N]; 40 int qu[N], beg, tail; 41 42 void init( int n ) { 43 for( int i=1; i<=n; i++ ) { 44 g[i].clear(); 45 st[i].clear(); 46 bit[i].clear(); 47 vis[i] = false; 48 } 49 } 50 void build( int root ) { 51 qu[beg=tail=0] = root; 52 anc[root] = root; 53 siz[root] = bac[root] = 0; 54 while( tail>=beg ) { 55 int u=qu[beg++]; 56 for( int t=0; t<g[u].size(); t++ ) { 57 int v=g[u][t]; 58 if( v==anc[u] || vis[v] ) continue; 59 qu[++tail] = v; 60 anc[v] = u; 61 siz[v] = bac[v] = 0; 62 } 63 } 64 for( int i=tail; i; i-- ) { 65 int v=qu[i]; 66 int u=anc[v]; 67 siz[v]++; 68 siz[u]+=siz[v]; 69 if( siz[v]>bac[u] ) bac[u]=siz[v]; 70 } 71 for( int i=0; i<=tail; i++ ) { 72 int u = qu[i]; 73 if( siz[root]-siz[u]>bac[u] ) bac[u]=siz[root]-siz[u]; 74 } 75 for( int i=0; i<=tail; i++ ) { 76 int u = qu[i]; 77 if( bac[u]<bac[root] ) root=u; 78 } 79 //---------------- found the core -------------------// 80 bit[root][0].init( tail+1 ); 81 bit[root][0].modify( 0, ww[root] ); 82 st[root].push_back( Stat(root,0,0) ); 83 vis[root] = true; 84 85 86 anc[root] = root; 87 for( int t=0; t<g[root].size(); t++ ) { 88 int sr = g[root][t]; 89 if( vis[sr] ) continue; 90 qu[beg=tail=0] = sr; 91 dis[sr] = 1; 92 anc[sr] = root; 93 while( tail>=beg ) { 94 int u=qu[beg++]; 95 for( int t=0; t<g[u].size(); t++ ) { 96 int v=g[u][t]; 97 if( vis[v] || v==anc[u] ) continue; 98 qu[++tail] = v; 99 dis[v] = dis[u]+1; 100 anc[v] = u; 101 } 102 } 103 bit[root][sr].init( tail+2 ); 104 for( int i=0; i<=tail; i++ ) { 105 int u=qu[i]; 106 bit[root][0].modify( dis[u], ww[u] ); 107 bit[root][sr].modify( dis[u], ww[u] ); 108 st[u].push_back( Stat(root,dis[u],sr) ); 109 } 110 } 111 for( int t=0; t<g[root].size(); t++ ) { 112 int v=g[root][t]; 113 if( vis[v] ) continue; 114 build(g[root][t]); 115 } 116 } 117 void modify( int u, int d ) { 118 for( int t=0; t<st[u].size(); t++ ) { 119 Stat &s = st[u][t]; 120 bit[s.r][0].modify( s.d, d ); 121 if( s.s ) bit[s.r][s.s].modify( s.d, d ); 122 } 123 } 124 int query( int u, int d ) { 125 int rt = 0; 126 for( int t=0; t<st[u].size(); t++ ) { 127 Stat &s = st[u][t]; 128 if( d<s.d ) continue; 129 int v = bit[s.r][0].query( d-s.d ); 130 rt += v; 131 if( s.s ) { 132 v = bit[s.r][s.s].query( d-s.d ); 133 rt -= v; 134 } 135 } 136 return rt; 137 } 138 139 int main() { 140 while(1) { 141 if( scanf( "%d%d", &n, &m )!=2 ) return 0; 142 init(n); 143 for( int i=1; i<=n; i++ ) 144 scanf( "%d", ww+i ); 145 for( int i=1,u,v; i<n; i++ ) { 146 scanf( "%d%d", &u, &v ); 147 g[u].push_back( v ); 148 g[v].push_back( u ); 149 } 150 build(1); 151 for( int i=1; i<=m; i++ ) { 152 char ch[10]; 153 int u, d; 154 scanf( "%s%d%d", ch, &u, &d ); 155 if( ch[0]=='!' ) { 156 modify( u, d-ww[u] ); 157 ww[u] = d; 158 } else { 159 printf( "%d\n", query(u,d) ); 160 } 161 } 162 } 163 } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/idy002/p/4366969.html

總結(jié)

以上是生活随笔為你收集整理的hdu 4918的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。