1. 很想参加cf的div2,但是时间是凌晨12点半,实在没办法参加。
2. 这次碰到二分的题目,遇到二分,还是优先使用lower_bound和upper_bound,理解清楚这两个函数的用法,其次,才是自己写二分,一般判别函数是自定义的话,都需要自己实现二分。恰巧就是上次说的,求满足什么要求的最大值,然后就是注意mid = (left + right + 1) / 2,这个条件,真的很重要。
3.碰到一个问题,首先是ac,然后才是考虑怎么进行优化。accept code is better than efficient code but paritical correct.
4.注意vector的erase是O(n)的,上次也是什么优化问题,nlogn可以过,然后由于哪里错了,导致n^2,就tle了。想起来了,使用了memset,然后O(n)的复杂度,然后自己还没反应过了,结果tle了。
5.做题的 时候还是经常缺少考虑一些边界条件。
6. 一般自己多想几个测试用例,测试一下自己的程序,而不要仅限于给出的例子。尤其是一些边界条件。
7. 以前不会写怎么进行缩边,这次应该算是知道了。如果有些知识点你不知道,或者你没有想法怎么实现,那么真正用的时候,很大可能是写不出来的。
缩边,缩边很重要,这么重要的知识点,为什么这里不贴一下代码和思路呢?说不定以后还需要回过头来看看!
http://codeforces.com/contest/734/problem/E 缩边的题目是这道题,缩边后,找树的直径。虽然找树的直径很好写,但是一般不容易分析出这个题目是求解树的直径!
下面的代码是我抄标程的代码,dfs2不好理解,而且我一般不这么写,根据自己需要吧!
1 #include<bits/stdc++.h> 2 #define pb push_back 3 #define FOR(i, n) for (int i = 0; i < (int)n; ++i) 4 #define dbg(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl 5 typedef long long ll; 6 using namespace std; 7 typedef pair<int, int> pii; 8 const int maxn = 2e5 + 10; 9 vector<int> e[maxn]; 10 int color[maxn]; 11 int n; 12 bool vis[maxn]; 13 int conn[maxn]; 14 vector<int> e2[maxn]; 15 void dfs(int x, int c, int tag) { 16 vis[x] = 1; 17 conn[x] = tag; 18 for (auto u : e[x]) { 19 if(vis[u] || color[u] != c) continue; 20 dfs(u, c, tag); 21 } 22 } 23 int ans; 24 int dfs2(int u, int p) { 25 int a, b; 26 a = b = 0; 27 for (auto x : e2[u]) { 28 if(x == p) continue; 29 int v = dfs2(x, u) + 1; 30 if(v > b) b = v; 31 if(a < b) swap(a, b); 32 } 33 ans = max(ans, a + b); 34 return a; 35 } 36 void solve() { 37 cin >> n; 38 for (int i = 0; i < n; i++) cin >> color[i]; 39 int x, y; 40 for (int i = 0; i < n - 1; i++) { 41 cin >> x >> y; 42 x--; y--; 43 e[x].pb(y); 44 e[y].pb(x); 45 } 46 int cnt = 0; 47 for (int i = 0; i < n; i++) { 48 if(!vis[i]) { 49 //cout << i << endl; 50 dfs(i, color[i], cnt); 51 cnt++; 52 } 53 } 54 //cout << cnt << endl; 55 for (int i = 0; i < n; i++) { 56 for (auto j : e[i]) { 57 if(conn[i] != conn[j]) { 58 e2[conn[i] ].pb(conn[j]); 59 //e2[conn[j] ].pb(conn[i]); 60 //cout << conn[i] << " " << conn[j] << endl; 61 } 62 } 63 } 64 dfs2(0, -1); 65 cout << (ans + 1) / 2 << endl; 66 } 67 int main() { 68 //freopen("test.in", "r", stdin); 69 //freopen("test.out", "w", stdout); 70 solve(); 71 return 0; 72 }
8. 还有位操作,还是老套路,就是拆位,把每一位分开讨论。这应该是亘古不变的,看到位操作的题目,一定要马上想起来拆位,拆位,再拆位。
http://codeforces.com/contest/734/problem/F 拆位的题目是这道,性质不容易分析出来,需要思考。构造出结果以后,还需要进行验证,我没有做出来。讲真,我也就div2 2道题的水平。