bzoj3451 Normal
题意:点分治每次随机选重心,求期望复杂度。
发现一次点分治的复杂度就是点分树上每个节点的子树大小之和。(并没有发现......)
看这个。
注意这个写法有问题,随便来个菊花图就是n2了。
每一层点分治的时候,时间复杂度决不能与上一层大小挂钩。
1 /************************************************************** 2 Problem: 3451 3 Language: C++ 4 Result: Accepted 5 Time:5548 ms 6 Memory:8548 kb 7 ****************************************************************/ 8 9 #include <cstdio> 10 #include <algorithm> 11 #include <cstring> 12 #include <cmath> 13 14 typedef long long LL; 15 typedef long double LD; 16 const LD pi = 3.1415926535897932384626; 17 const int N = 30010, INF = 0x3f3f3f3f; 18 19 inline void read(int &x) { 20 x = 0; 21 char c = getchar(); 22 while(c < '0' || c > '9') { 23 c = getchar(); 24 } 25 while(c >= '0' && c <= '9') { 26 x = (x << 3) + (x << 1) + c - 48; 27 c = getchar(); 28 } 29 return; 30 } 31 32 struct cp { 33 LD x, y; 34 cp(LD X = 0, LD Y = 0) { 35 x = X; 36 y = Y; 37 } 38 inline cp operator +(const cp &w) const { 39 return cp(x + w.x, y + w.y); 40 } 41 inline cp operator -(const cp &w) const { 42 return cp(x - w.x, y - w.y); 43 } 44 inline cp operator *(const cp &w) const { 45 return cp(x * w.x - y * w.y, x * w.y + y * w.x); 46 } 47 }a[N * 4], b[N * 4]; 48 49 struct Edge { 50 int nex, v; 51 }edge[N << 1]; int tp; 52 53 int r[N * 4], n, e[N], small, root, d[N], bin[N], cnt[N], _n, siz[N]; 54 bool del[N]; 55 56 inline void add(int x, int y) { 57 tp++; 58 edge[tp].v = y; 59 edge[tp].nex = e[x]; 60 e[x] = tp; 61 return; 62 } 63 64 inline void FFT(cp *a, int n, int f) { 65 for(register int i = 0; i < n; i++) { 66 if(i < r[i]) { 67 std::swap(a[i], a[r[i]]); 68 } 69 } 70 for(register int len = 1; len < n; len <<= 1) { 71 cp Wn(cos(pi / len), f * sin(pi / len)); 72 for(register int i = 0; i < n; i += (len << 1)) { 73 cp w(1, 0); 74 for(register int j = 0; j < len; j++) { 75 cp t = a[i + len + j] * w; 76 a[i + len + j] = a[i + j] - t; 77 a[i + j] = a[i + j] + t; 78 w = w * Wn; 79 } 80 } 81 } 82 if(f == -1) { 83 for(register int i = 0; i <= n; i++) { 84 a[i].x /= n; 85 } 86 } 87 return; 88 } 89 90 inline void cal(int n, int f) { 91 /*printf("cal \n"); 92 for(int i = 0; i <= n; i++) { 93 printf("%d ", bin[i]); 94 } 95 printf("\n");*/ 96 int lm = 1, len = 2; 97 while(len <= n * 2) { 98 len <<= 1; 99 lm++; 100 } 101 for(register int i = 0; i <= len; i++) { 102 r[i] = (r[i >> 1] >> 1) | ((i & 1) << (lm - 1)); 103 } 104 for(register int i = 0; i <= n; i++) { 105 a[i] = cp(bin[i], 0); 106 } 107 for(register int i = n + 1; i <= len; i++) { 108 a[i] = cp(0, 0); 109 } 110 FFT(a, len, 1); 111 for(register int i = 0; i <= len; i++) { 112 a[i] = a[i] * a[i]; 113 } 114 FFT(a, len, -1); 115 /*for(int i = 0; i <= n + n; i++) { 116 printf("%d ", (int)(a[i].x + 0.5)); 117 } 118 printf("\n");*/ 119 for(register int i = 0; i <= len; i++) { 120 cnt[i] += f * (int)(a[i].x + 0.5); 121 } 122 return; 123 } 124 125 void get_root(int x, int f) { 126 bin[d[x]]++; 127 siz[x] = 1; 128 int large = -1; 129 for(int i = e[x]; i; i = edge[i].nex) { 130 int y = edge[i].v; 131 if(y == f || del[y]) { 132 continue; 133 } 134 get_root(y, x); 135 siz[x] += siz[y]; 136 large = std::max(large, siz[y]); 137 } 138 if(small > std::max(large, _n - siz[x])) { 139 small = std::max(large, _n - siz[x]); 140 root = x; 141 } 142 return; 143 } 144 145 void DFS(int x, int f) { 146 d[x] = d[f] + 1; 147 bin[d[x]]++; 148 siz[x] = 1; 149 for(int i = e[x]; i; i = edge[i].nex) { 150 int y = edge[i].v; 151 if(y == f || del[y]) { 152 continue; 153 } 154 DFS(y, x); 155 siz[x] += siz[y]; 156 } 157 return; 158 } 159 160 void div(int x, int f, int last_n) { 161 if(f) { 162 memset(bin, 0, sizeof(int) * (last_n + 1)); 163 } 164 small = INF; 165 get_root(x, 0); 166 if(f) { 167 cal(last_n, -1); 168 } 169 x = root; 170 memset(bin, 0, sizeof(int) * (_n + 1)); 171 DFS(x, 0); 172 cal(_n, 1); 173 del[x] = 1; 174 for(int i = e[x]; i; i = edge[i].nex) { 175 int y = edge[i].v; 176 if(del[y]) { 177 continue; 178 } 179 _n = siz[y]; 180 div(y, 1, siz[x]); 181 } 182 return; 183 } 184 185 int main() { 186 d[0] = -1; 187 read(n); 188 for(register int i = 1, x, y; i < n; i++) { 189 read(x); read(y); 190 add(x + 1, y + 1); add(y + 1, x + 1); 191 } 192 193 _n = n; 194 div(1, 0, n); 195 LD ans = 0; 196 /*for(int i = 0; i <= n; i++) { 197 printf("%d ", cnt[i]); 198 } 199 printf("\n");*/ 200 for(register int i = 0; i < n; i++) { 201 ans += (LD)cnt[i] / (i + 1); 202 } 203 printf("%.4Lf\n", ans); 204 return 0; 205 }
注意FFT里面j从0开始,到len。