2013多校训练赛第一场 总结
http://acm.hdu.edu.cn/listproblem.php?vol=37
hdu 4600~4610 2013HDU多校训练第一场
这次的组队训练好没状态,居然敲几题水题都搞了2个多种。最后我们队做出了4题,排在41名。
不太想写东西,直接上题解了:
这题做法其实还没想到,不过写出了一个能过目前所有数据的代码(比赛的时候数据更水,几乎算不出正确答案的代码都能过):
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <map> 6 7 using namespace std; 8 9 const int N = 111111; 10 11 int rec[N], dp1[N], dp2[N], same[N]; 12 int s[N], top; 13 14 int find1(int x) { 15 int l = 0, r = top, m, mk = -1; 16 while (l <= r) { 17 m = l + r >> 1; 18 if (s[m] >= x) mk = m, l = m + 1; 19 else r = m - 1; 20 } 21 return mk; 22 } 23 24 void DP1(int n) { 25 top = -1; 26 for (int i = n - 1; i >= 0; i--) { 27 int pos = find1(rec[i]) + 1; 28 dp1[i] = pos + 1; 29 if (pos > top) s[++top] = rec[i]; 30 else s[pos] = max(s[pos], rec[i]); 31 } 32 } 33 34 void DP2(int n) { 35 top = -1; 36 for (int i = n - 1; i >= 0; i--) { 37 int pos = (int) (upper_bound(s, s + top + 1, rec[i]) - s); 38 dp2[i] = pos + 1; 39 if (pos > top) s[++top] = rec[i]; 40 else s[pos] = min(s[pos], rec[i]); 41 same[i] = upper_bound(s, s + top + 1, rec[i]) - lower_bound(s, s + top + 1, rec[i]); 42 } 43 } 44 45 int main() { 46 int n, T; 47 scanf("%d", &T); 48 while (T-- && ~scanf("%d", &n)) { 49 for (int i = 0; i < n; i++) scanf("%d", &rec[i]); 50 DP1(n); 51 DP2(n); 52 int ans = 0; 53 //for (int i = 0; i < n; i++) cout << dp1[i] << ' '; cout << endl; 54 //for (int i = 0; i < n; i++) cout << dp2[i] << ' '; cout << endl; 55 //for (int i = 0; i < n; i++) cout << same[i] << ' '; cout << endl; 56 for (int i = 0; i < n; i++) ans = max(ans, dp1[i] + dp2[i] - same[i]); 57 printf("%d\n", ans); 58 } 59 return 0; 60 }
这里的做法是计算LIS了,然后去掉重复。可是根据题意,对于下面一组数据是应该输出5的:
5
1 1 11 1 1
不管了,先放着。
这题是用插板法,排列组合的题。队友出的,注意的是k有可能大于n:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <map> 6 #include <queue> 7 #include <stack> 8 #include <set> 9 10 using namespace std; 11 12 typedef long long LL; 13 const LL MOD = 1e9 + 7; 14 15 LL powmod(LL a, LL b) { 16 LL ret = 1; 17 while (b > 0) { 18 if (b & 1) ret *= a, ret %= MOD; 19 a *= a, a %= MOD; 20 b >>= 1; 21 } 22 return ret; 23 } 24 25 int main() { 26 int T; 27 LL n, k; 28 cin >> T; 29 while (T-- && ~scanf("%I64d%I64d", &n, &k)) { 30 if (n == k) puts("1"); 31 else if (n == k + 1) puts("2"); 32 else if (k < n){ 33 printf("%I64d\n", (powmod(2, n - k) + (n - k - 1) * powmod(2, n - k - 2)) % MOD); 34 } else puts("0"); 35 } 36 return 0; 37 }
这题是最水的了,不过真的很没状态啊,居然搞很久才过,幸亏1y了。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <map> 6 #include <queue> 7 #include <stack> 8 #include <set> 9 10 using namespace std; 11 12 const int N = 111111; 13 14 char str[N]; 15 int main() { 16 int T; 17 cin >> T; 18 while (T-- && cin >> str) { 19 int len = strlen(str), pos; 20 int sum = 0; 21 for (int i = 0; i < len; i++) sum += str[i] - '0'; 22 sum %= 10; 23 sum = 10 - sum; 24 if (str[len - 1] - '0' + sum < 10) { 25 str[len - 1] += sum; 26 puts(str); 27 } else { 28 str[len - 1] = '0'; 29 pos = len - 2; 30 while (pos >= 0 && str[pos] == '9') str[pos--] = '0'; 31 if (pos < 0) { 32 putchar('1'); 33 str[len - 1] = 0; 34 printf("%s", str); 35 puts("9"); 36 } else { 37 sum = 0; 38 str[pos]++; 39 for (int i = 0; i < len; i++) sum += str[i] - '0'; 40 sum %= 10; 41 str[len - 1] += (10 - sum) % 10; 42 puts(str); 43 } 44 } 45 } 46 return 0; 47 }
之后会陆续补充题解!
这次真的很没状态,代码各种没平时的飘逸。。需要调整一下!
UPD:
FFT,比赛的时候想到了比较接近的模型,可惜没有继续想下去。这里我们可以通过FFT达到快速完成多项式乘法的效果。最后debug了好久,多次发现因为有些变量没有用long long,wa了几次。
题意十分简单,就是给出若干边,问可以构成三角形的概率是多少。这里可以先求出反面例子,也就是两条边a+b<=c的情况,就是这里用了FFT,然后就是用全部情况减去枚举的每一个结果就行了。
带debug的代码如下:
1 #define code 1 2 3 #if (code == 1) 4 5 #include <cstdio> 6 #include <cstring> 7 #include <iostream> 8 #include <algorithm> 9 #include <cmath> 10 11 using namespace std; 12 13 const int N = 1 << 17; 14 const double PI = acos(-1.0); 15 16 struct Vir { 17 double r, i; 18 Vir() {} 19 Vir(double r, double i) : r(r), i(i) {} 20 Vir operator + (Vir &x) { return Vir(r + x.r, i + x.i);} 21 Vir operator - (Vir &x) { return Vir(r - x.r, i - x.i);} 22 Vir operator * (Vir &x) { return Vir(r * x.r - i * x.i, r * x.i + i * x.r);} 23 } rev[N << 1], v1[N << 1], v2[N << 1]; 24 25 const int M = 22; 26 int ep[M]; 27 double base[M], cosb[M], sinb[M]; 28 29 void PRE() { 30 ep[0] = 1; 31 for (int i = 1; i < M; i++) ep[i] = ep[i - 1] << 1; 32 for (int i = 0; i < M - 1; i++) base[i] = 2 * PI / ep[i + 1]; 33 for (int i = 0; i < M - 1; i++) sinb[i] = sin(base[i]), cosb[i] = cos(base[i]); 34 } 35 36 inline int revbit(int x, int l) { 37 int ret = 0; 38 while (l--) ret <<= 1, ret |= x & 1, x >>= 1; 39 return ret; 40 } 41 42 inline void reverse(Vir *a, int len) { 43 int bits = (int) ceil(log((double) len) / log(2.0)); 44 for (int i = 0; i < len; i++) rev[revbit(i, bits)] = a[i]; 45 for (int i = 0; i < len; i++) a[i] = rev[i]; 46 } 47 48 const Vir unit = Vir(1.0, 0.0); 49 50 void fft(Vir *a, int len, bool idft) { 51 Vir u, t; 52 int bits = (int) ceil(log((double) len) / log(2.0)); 53 reverse(a, len); 54 for (int i = 0; i < bits; i++) { 55 Vir wi, w; 56 wi.r = cosb[i]; 57 wi.i = idft ? -sinb[i] : sinb[i]; 58 for (int k = 0; k < len; k+= ep[i + 1]) { 59 w = unit; 60 for (int j = 0; j < ep[i]; j++) { 61 t = w * a[k + j + ep[i]]; 62 u = a[k + j]; 63 a[k + j] = u + t; 64 a[k + j + ep[i]] = u - t; 65 w = w * wi; 66 } 67 } 68 } 69 if (idft) for (int i = 0; i < len; i++) a[i].r /= len; 70 } 71 72 void cal(Vir *a, Vir *b, int len) { 73 fft(a, len, 0); 74 fft(b, len, 0); 75 for (int i = 0; i < len; i++) a[i] = a[i] * b[i]; 76 fft(a, len, 1); 77 } 78 79 int rec[N]; 80 typedef long long LL; 81 LL cnt[N << 1]; 82 83 bool test(int a, int b, int c) { 84 if (a + b <= c) return false; 85 if (a + c <= b) return false; 86 if (b + c <= a) return false; 87 return true; 88 } 89 90 double BF(int n) { 91 int cnt = 0; 92 for (int i = 0; i < n; i++) { 93 for (int j = i + 1; j < n; j++) { 94 for (int k = j + 1; k < n; k++) { 95 cnt += test(rec[i], rec[j], rec[k]); 96 } 97 } 98 } 99 return 6.0 * cnt / (n * (n - 1) * (n - 2)); 100 } 101 102 int main() { 103 // freopen("in", "r", stdin); 104 int n, x, T; 105 PRE(); 106 cin >> T; 107 while (T-- && cin >> n) { 108 memset(v1, 0, sizeof(v1)); 109 memset(v2, 0, sizeof(v2)); 110 int mx = 0; 111 for (int i = 0; i < n; i++) { 112 scanf("%d", &x); 113 rec[i] = x; 114 v1[x].r += 1.0; 115 v2[x].r += 1.0; 116 mx = max(x, mx); 117 } 118 mx++; 119 int len = 0; 120 while (ep[len] < mx) len++; 121 len = ep[len + 1]; 122 cal(v1, v2, len); 123 // cout << len << endl; 124 LL tt = (LL) n * (n - 1) * (n - 2) / 6, ans = tt; 125 // cout << tt << endl; 126 for (int i = 0; i < len; i++) cnt[i] = (LL) floor(v1[i].r + 0.5); 127 // for (int i = 0; i < 16; i++) cout << i << ' ' << v1[i].r << endl; 128 for (int i = 0; i < n; i++) cnt[rec[i] << 1]--; 129 // for (int i = 0; i < 16; i++) cout << i << ' ' << cnt[i] << endl; 130 for (int i = 0; i < len; i++) { 131 cnt[i] >>= 1; 132 cnt[i] += cnt[i - 1]; 133 } 134 for (int i = 0; i < n; i++) ans -= cnt[rec[i]]; 135 // cout << ans << endl; 136 printf("%.7f\n", ans * 1.0 / tt); 137 // double ansbf; 138 // printf("%.7f BruceForce~~~\n", ansbf = BF(n)); 139 // if (fabs(ans * 1.0 / tt - ansbf) > 1e-7) { 140 // freopen("out", "w", stdout); 141 // puts("1"); 142 // cout << n << endl; 143 // for (int i = 0; i < n; i++) cout << rec[i] << ' '; cout << endl; 144 // puts("WTF?!?!?!?!?!"); 145 // break; 146 // } 147 } 148 return 0; 149 } 150 151 #else 152 153 #include <cstdio> 154 #include <cstring> 155 #include <iostream> 156 #include <algorithm> 157 #include <ctime> 158 #include <cmath> 159 160 using namespace std; 161 162 const int T = 1000; 163 const int MAXN = 1000; 164 const int DIF = 10; 165 const int MAXNUM = 100000; 166 167 int main() { 168 freopen("in", "w", stdout); 169 cout << 1 << endl << 100000 << endl; 170 for (int i = 0; i < 100000; i++) cout << rand() % 2 + 1 << ' '; cout << endl; 171 // int t = T >> 2; 172 // srand(time(0)); 173 // cout << T << endl; 174 // while (t--) { 175 // int n = MAXN - DIF + 1 + rand() % DIF; 176 // cout << n << endl; 177 // while (n--) cout << rand() % 10 + 1 << ' '; 178 // cout << endl; 179 // } 180 // t = T >> 2; 181 // while (t--) { 182 // int n = MAXN - DIF + 1 + rand() % DIF; 183 // cout << n << endl; 184 // while (n--) cout << rand() % 100 + 1 << ' '; 185 // cout << endl; 186 // } 187 // t = T >> 2; 188 // while (t--) { 189 // int n = MAXN - DIF + 1 + rand() % DIF; 190 // cout << n << endl; 191 // while (n--) cout << rand() % 1000 + 1 << ' '; 192 // cout << endl; 193 // } 194 // t = T >> 2; 195 // while (t--) { 196 // int n = MAXN - DIF + 1 + rand() % DIF; 197 // cout << n << endl; 198 // while (n--) cout << rand() % MAXNUM + 1 << ' '; 199 // cout << endl; 200 // } 201 return 0; 202 } 203 204 #endif
上面的代码写了个暴力对拍,可惜最后还是想到数据,然后找到错误的数据,最后修改过来通过的。
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 7 using namespace std; 8 9 const int N = 1 << 17; 10 const double PI = acos(-1.0); 11 12 struct Vir { 13 double r, i; 14 Vir() {} 15 Vir(double r, double i) : r(r), i(i) {} 16 Vir operator + (Vir &x) { return Vir(r + x.r, i + x.i);} 17 Vir operator - (Vir &x) { return Vir(r - x.r, i - x.i);} 18 Vir operator * (Vir &x) { return Vir(r * x.r - i * x.i, r * x.i + i * x.r);} 19 } rev[N << 1], v1[N << 1], v2[N << 1]; 20 21 const int M = 22; 22 int ep[M]; 23 double base[M], cosb[M], sinb[M]; 24 25 void PRE() { 26 ep[0] = 1; 27 for (int i = 1; i < M; i++) ep[i] = ep[i - 1] << 1; 28 for (int i = 0; i < M - 1; i++) base[i] = 2 * PI / ep[i + 1]; 29 for (int i = 0; i < M - 1; i++) sinb[i] = sin(base[i]), cosb[i] = cos(base[i]); 30 } 31 32 inline int revbit(int x, int l) { 33 int ret = 0; 34 while (l--) ret <<= 1, ret |= x & 1, x >>= 1; 35 return ret; 36 } 37 38 inline void reverse(Vir *a, int len) { 39 int bits = (int) ceil(log((double) len) / log(2.0)); 40 for (int i = 0; i < len; i++) rev[revbit(i, bits)] = a[i]; 41 for (int i = 0; i < len; i++) a[i] = rev[i]; 42 } 43 44 const Vir unit = Vir(1.0, 0.0); 45 46 void fft(Vir *a, int len, bool idft) { 47 Vir u, t; 48 int bits = (int) ceil(log((double) len) / log(2.0)); 49 reverse(a, len); 50 for (int i = 0; i < bits; i++) { 51 Vir wi, w; 52 wi.r = cosb[i]; 53 wi.i = idft ? -sinb[i] : sinb[i]; 54 for (int k = 0; k < len; k+= ep[i + 1]) { 55 w = unit; 56 for (int j = 0; j < ep[i]; j++) { 57 t = w * a[k + j + ep[i]]; 58 u = a[k + j]; 59 a[k + j] = u + t; 60 a[k + j + ep[i]] = u - t; 61 w = w * wi; 62 } 63 } 64 } 65 if (idft) for (int i = 0; i < len; i++) a[i].r /= len; 66 } 67 68 void cal(Vir *a, Vir *b, int len) { 69 fft(a, len, 0); 70 fft(b, len, 0); 71 for (int i = 0; i < len; i++) a[i] = a[i] * b[i]; 72 fft(a, len, 1); 73 } 74 75 int rec[N]; 76 typedef long long LL; 77 LL cnt[N << 1]; 78 79 bool test(int a, int b, int c) { 80 if (a + b <= c) return false; 81 if (a + c <= b) return false; 82 if (b + c <= a) return false; 83 return true; 84 } 85 86 double BF(int n) { 87 int cnt = 0; 88 for (int i = 0; i < n; i++) { 89 for (int j = i + 1; j < n; j++) { 90 for (int k = j + 1; k < n; k++) { 91 cnt += test(rec[i], rec[j], rec[k]); 92 } 93 } 94 } 95 return 6.0 * cnt / (n * (n - 1) * (n - 2)); 96 } 97 98 int main() { 99 int n, x, T; 100 PRE(); 101 cin >> T; 102 while (T-- && cin >> n) { 103 memset(v1, 0, sizeof(v1)); 104 memset(v2, 0, sizeof(v2)); 105 int mx = 0; 106 for (int i = 0; i < n; i++) { 107 scanf("%d", &x); 108 rec[i] = x; 109 v1[x].r += 1.0; 110 v2[x].r += 1.0; 111 mx = max(x, mx); 112 } 113 mx++; 114 int len = 0; 115 while (ep[len] < mx) len++; 116 len = ep[len + 1]; 117 cal(v1, v2, len); 118 LL tt = (LL) n * (n - 1) * (n - 2) / 6, ans = tt; 119 for (int i = 0; i < len; i++) cnt[i] = (LL) floor(v1[i].r + 0.5); 120 for (int i = 0; i < n; i++) cnt[rec[i] << 1]--; 121 for (int i = 0; i < len; i++) { 122 cnt[i] >>= 1; 123 cnt[i] += cnt[i - 1]; 124 } 125 for (int i = 0; i < n; i++) ans -= cnt[rec[i]]; 126 printf("%.7f\n", ans * 1.0 / tt); 127 } 128 return 0; 129 }
UPD:
题意是,给定一棵点上带权的树,要求求出从根出发到达给定结点按照要求求出的概率值。
这题可以有很多做法,比较容易想到的可能是树链剖分,不过这题用树链剖分的话估计vector之类的stl会导致超时。这题有一个简单的方法,就是在遍历树的时候同时处理query,也就是离线处理。遍历的过程中,记录两样东西,一个是从根结点到当前结点有哪些权值,另一个是从根结点到当前结点需要向右走的结点有哪些权值。
遍历到当前结点的时候,求出有多少个已存的权值比当前权值小和大,还有多少个已存的向右走的结点的权值比当前权值小。
加了个栈挂,1y~
代码如下:
1 #pragma comment(linker, "/STACK:102400000,102400000") 2 3 #include <cstdio> 4 #include <iostream> 5 #include <algorithm> 6 #include <cstring> 7 #include <map> 8 9 using namespace std; 10 11 const int N = 111111; 12 struct Node { 13 int w, c[2]; 14 } node[N]; 15 map<int, int> id; 16 int rx[N]; 17 18 inline int lowbit(int x) { return x & (-x);} 19 struct BIT { 20 int s[N << 1], sz, tt; 21 void init(int size) { memset(s, 0, sizeof(s)); sz = size + 10, tt = 0;} 22 void inc(int x) { tt++, x += 10; for ( ; x < N; x += lowbit(x)) s[x]++;} 23 void dec(int x) { tt--, x += 10; for ( ; x < N; x += lowbit(x)) s[x]--;} 24 int sum(int x) { 25 int ret = 0; 26 for (x += 10; x > 0; x -= lowbit(x)) ret += s[x]; 27 return ret; 28 } 29 int sum(int l, int r) { return sum(r) - sum(l - 1);} 30 } all, rt; 31 32 struct Query { 33 int x, nx, id; 34 Query() {} 35 Query(int x, int nx, int id) : x(x), nx(nx), id(id) {} 36 } qry[N]; 37 int qs[N], qc; 38 int q1[N], q2[N], cnt[N]; 39 40 void init() { 41 memset(qs, -1, sizeof(qs)); 42 qc = 0; 43 } 44 45 void addqry(int v, int x, int id) { 46 qry[qc] = Query(x, qs[v], id); 47 qs[v] = qc++; 48 } 49 50 void dfs(int x) { 51 int wt = id[node[x].w], t; 52 for (t = qs[x]; ~t; t = qry[t].nx) { 53 Query &q = qry[t]; 54 if (cnt[id[q.x]]) { 55 q1[q.id] = -1; 56 continue; 57 } 58 int w = id[q.x]; 59 int lwr = all.sum(w - 1), upr = all.tt - lwr - cnt[w]; 60 int lw = rt.sum(w - 1); 61 q1[q.id] = lw; 62 q2[q.id] = upr + lwr * 3; 63 } 64 all.inc(wt); 65 cnt[wt]++; 66 if (~node[x].c[0]) dfs(node[x].c[0]); 67 rt.inc(wt); 68 if (~node[x].c[1]) dfs(node[x].c[1]); 69 rt.dec(wt); 70 all.dec(wt); 71 cnt[wt]--; 72 } 73 74 bool nrt[N]; 75 76 int main() { 77 // freopen("in", "r", stdin); 78 int T, n, m, q; 79 int x, y, f; 80 scanf("%d", &T); 81 while (T-- && ~scanf("%d", &n)) { 82 id.clear(); 83 for (int i = 1; i <= n; i++) { 84 scanf("%d", &node[i].w); 85 rx[i - 1] = node[i].w; 86 node[i].c[0] = node[i].c[1] = -1; 87 } 88 memset(nrt, 0, sizeof(nrt)); 89 scanf("%d", &m); 90 while (m--) { 91 scanf("%d%d%d", &f, &x, &y); 92 node[f].c[0] = x, node[f].c[1] = y; 93 nrt[x] = nrt[y] = true; 94 } 95 init(); 96 scanf("%d", &q); 97 for (int i = 0; i < q; i++) { 98 scanf("%d%d", &x, &y); 99 rx[i + n] = y; 100 addqry(x, y, i); 101 } 102 sort(rx, rx + n + q); 103 m = (int) (unique(rx, rx + n + q) - rx); 104 all.init(m); 105 rt.init(m); 106 for (int i = 0; i < m; i++) id[rx[i]] = i; 107 int rt = -1; 108 for (int i = 1; i <= n; i++) if (!nrt[i]) rt = i; 109 if (rt == -1) { 110 puts("WTF?!"); 111 while (1) ; 112 } 113 dfs(1); 114 for (int i = 0; i < q; i++) { 115 if (q1[i] == -1) puts("0"); 116 else printf("%d %d\n", q1[i], q2[i]); 117 } 118 } 119 return 0; 120 }
UPD:
改成非递归的:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <map> 6 7 using namespace std; 8 9 const int N = 111111; 10 struct Node { 11 int w, c[2]; 12 } node[N]; 13 map<int, int> id; 14 int rx[N]; 15 16 inline int lowbit(int x) { return x & (-x);} 17 struct BIT { 18 int s[N << 1], sz, tt; 19 void init(int size) { memset(s, 0, sizeof(s)); sz = size + 10, tt = 0;} 20 void inc(int x) { tt++, x += 10; for ( ; x < N; x += lowbit(x)) s[x]++;} 21 void dec(int x) { tt--, x += 10; for ( ; x < N; x += lowbit(x)) s[x]--;} 22 int sum(int x) { 23 int ret = 0; 24 for (x += 10; x > 0; x -= lowbit(x)) ret += s[x]; 25 return ret; 26 } 27 int sum(int l, int r) { return sum(r) - sum(l - 1);} 28 } all, rt; 29 30 struct Query { 31 int x, nx, id; 32 Query() {} 33 Query(int x, int nx, int id) : x(x), nx(nx), id(id) {} 34 } qry[N]; 35 int qs[N], qc; 36 int q1[N], q2[N], cnt[N]; 37 38 void init() { 39 memset(qs, -1, sizeof(qs)); 40 qc = 0; 41 } 42 43 void addqry(int v, int x, int id) { 44 qry[qc] = Query(x, qs[v], id); 45 qs[v] = qc++; 46 } 47 48 int sv[N], top; 49 int vis[N]; 50 void dfs(int x) { 51 top = -1; 52 sv[++top] = x; 53 vis[top] = 0; 54 while (top >= 0) { 55 x = sv[top]; 56 int st = vis[top--], wt = id[node[x].w], t; 57 if (st == 0) { 58 for (t = qs[x]; ~t; t = qry[t].nx) { 59 Query &q = qry[t]; 60 if (cnt[id[q.x]]) { 61 q1[q.id] = -1; 62 continue; 63 } 64 int w = id[q.x]; 65 int lwr = all.sum(w - 1), upr = all.tt - lwr - cnt[w]; 66 int lw = rt.sum(w - 1); 67 q1[q.id] = lw; 68 q2[q.id] = upr + lwr * 3; 69 } 70 all.inc(wt); 71 cnt[wt]++; 72 sv[++top] = x; 73 vis[top] = 1; 74 if (~node[x].c[0]) sv[++top] = node[x].c[0], vis[top] = 0; 75 } else if (st == 1) { 76 rt.inc(wt); 77 sv[++top] = x; 78 vis[top] = 2; 79 if (~node[x].c[1]) sv[++top] = node[x].c[1], vis[top] = 0; 80 } else { 81 rt.dec(wt); 82 all.dec(wt); 83 cnt[wt]--; 84 } 85 } 86 } 87 88 bool nrt[N]; 89 90 int main() { 91 // freopen("in", "r", stdin); 92 int T, n, m, q; 93 int x, y, f; 94 scanf("%d", &T); 95 while (T-- && ~scanf("%d", &n)) { 96 id.clear(); 97 for (int i = 1; i <= n; i++) { 98 scanf("%d", &node[i].w); 99 rx[i - 1] = node[i].w; 100 node[i].c[0] = node[i].c[1] = -1; 101 } 102 memset(nrt, 0, sizeof(nrt)); 103 scanf("%d", &m); 104 while (m--) { 105 scanf("%d%d%d", &f, &x, &y); 106 node[f].c[0] = x, node[f].c[1] = y; 107 nrt[x] = nrt[y] = true; 108 } 109 init(); 110 scanf("%d", &q); 111 for (int i = 0; i < q; i++) { 112 scanf("%d%d", &x, &y); 113 rx[i + n] = y; 114 addqry(x, y, i); 115 } 116 sort(rx, rx + n + q); 117 m = (int) (unique(rx, rx + n + q) - rx); 118 all.init(m); 119 rt.init(m); 120 for (int i = 0; i < m; i++) id[rx[i]] = i; 121 int rt = -1; 122 for (int i = 1; i <= n; i++) if (!nrt[i]) rt = i; 123 if (rt == -1) { 124 puts("WTF?!"); 125 while (1) ; 126 } 127 dfs(1); 128 for (int i = 0; i < q; i++) { 129 if (q1[i] == -1) puts("0"); 130 else printf("%d %d\n", q1[i], q2[i]); 131 } 132 } 133 return 0; 134 }
UPD:
贴一下队友ly的1008(hdu 4607)的代码:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <map> 6 #include <queue> 7 #include <stack> 8 #include <set> 9 10 const int N = 1e5+5; 11 const int inf = 1<<28; 12 using namespace std; 13 int n,m; 14 int tot,pre[N]; 15 struct edge{ 16 int v,next; 17 }e[N<<1]; 18 19 void init(){ 20 tot=0; 21 memset(pre,-1,sizeof(pre)); 22 } 23 24 void add(int u,int v){ 25 edge E={v,pre[u]}; 26 e[tot]=E,pre[u]=tot++; 27 } 28 29 void input(){ 30 int u,v; 31 scanf("%d%d",&n,&m); 32 for(int i=1;i<n;i++){ 33 scanf("%d%d",&u,&v); 34 add(u,v),add(v,u); 35 } 36 } 37 38 int dis[N],vis[N]; 39 int bfs(int s,int &t){ 40 queue<int> q; 41 memset(vis,0,sizeof(vis)); 42 dis[s]=0,vis[s]=1,t=s; 43 q.push(s); 44 int res=0; 45 while(!q.empty()){ 46 int u=q.front(); 47 q.pop(); 48 if(res<dis[u]){ 49 res=dis[u]; 50 t=u; 51 } 52 for(int i=pre[u];i!=-1;i=e[i].next){ 53 int v=e[i].v; 54 if(!vis[v]){ 55 dis[v]=dis[u]+1; 56 vis[v]=1; 57 q.push(v); 58 } 59 } 60 } 61 return res+1; 62 } 63 64 void query(){ 65 int k,u,v; 66 int tmp=bfs(1,v); 67 tmp=bfs(v,u); 68 while(m--){ 69 scanf("%d",&k); 70 if(k<=tmp) printf("%d\n",k-1); 71 else printf("%d\n",tmp-1+(k-tmp)*2); 72 } 73 } 74 75 int main(){ 76 int t; 77 scanf("%d",&t); 78 while(t--){ 79 init(); 80 input(); 81 query(); 82 } 83 return 0; 84 }
——written by Lyon