BZOJ 4390 [Usaco2015 dec]Max Flow
可以用树链剖分强行做,也可以用树上差分的做法。可以参考这篇blog:http://www.cnblogs.com/Created-equal/p/5111438.html
1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 const size_t Max_N(50050); 9 const size_t Max_M(100050); 10 const int root(1); 11 12 void Get_Val(int &Ret) 13 { 14 Ret = 0; 15 char ch; 16 while ((ch = getchar()), (ch > '9' || ch < '0')) 17 ; 18 do 19 { 20 (Ret *= 10) += ch -'0'; 21 } 22 while ((ch = getchar()), (ch >= '0' && ch <= '9')); 23 } 24 25 int N; 26 int Total; 27 int Head[Max_N]; 28 int To[Max_M], Next[Max_M]; 29 30 int K; 31 32 int Value[Max_N]; 33 int Father[Max_N], Deep[Max_N], Anc[Max_N][21]; 34 vector<int> Son[Max_N]; 35 36 int Ans; 37 38 inline 39 void Add_Edge(const int &s, const int &t) 40 { 41 ++Total; 42 To[Total] = t; 43 Next[Total] = Head[s], Head[s] = Total; 44 } 45 46 void make_tree(const int &u, const int &fa) 47 { 48 int v; 49 for (int i = Head[u];i;i = Next[i]) 50 { 51 v = To[i]; 52 if (v != fa) 53 { 54 Father[v] = u, Deep[v] = Deep[u] + 1; 55 Son[u].push_back(v); 56 make_tree(v, u); 57 } 58 } 59 } 60 61 void preprocess() 62 { 63 memset(Anc, -1, sizeof(Anc)); 64 for (int i = 1;i <= N;++i) 65 Anc[i][0] = Father[i]; 66 for (int j = 1;(1 << j) <= N;++j) 67 for (int i = 1;i <= N;++i) 68 Anc[i][j] = Anc[Anc[i][j - 1]][j - 1]; 69 } 70 71 int LCA(int p, int q) 72 { 73 if (Deep[p] < Deep[q]) 74 swap(p, q); 75 int log; 76 for (log = 1;(1 << log) <= Deep[p];++log); --log; 77 for (int i = log;i >= 0;--i) 78 if (Deep[p] - (1 << i) >= Deep[q]) 79 p = Anc[p][i]; 80 if (p == q) 81 return p; 82 for (int i = log;i >= 0;--i) 83 if (Anc[p][i] != -1 && Anc[p][i] != Anc[q][i]) 84 p = Anc[p][i], q = Anc[q][i]; 85 return Father[p]; 86 } 87 88 void init() 89 { 90 int x, y; 91 Get_Val(N), Get_Val(K); 92 for (int i = 1;i != N;++i) 93 { 94 Get_Val(x), Get_Val(y); 95 Add_Edge(x, y), Add_Edge(y, x); 96 } 97 Deep[root] = 1, make_tree(root, Father[root] = -1); 98 preprocess(); 99 } 100 101 void Add(const int &s, const int &t, const int &w) 102 { 103 int lca = LCA(s, t); 104 Value[s] += w, Value[t] += w, Value[lca] -= w; 105 if (lca != root) 106 Value[Father[lca]] -= w; 107 } 108 109 void DFS(const int &u) 110 { 111 for (vector<int>::size_type i = 0;i != Son[u].size();++i) 112 { 113 DFS(Son[u][i]); 114 Value[u] += Value[Son[u][i]]; 115 } 116 Ans = max(Ans, Value[u]); 117 } 118 119 void work() 120 { 121 int s, t; 122 while (K--) 123 { 124 Get_Val(s), Get_Val(t); 125 Add(s, t, 1); 126 } 127 DFS(root); 128 printf("%d", Ans); 129 } 130 131 int main() 132 { 133 init(); 134 work(); 135 return 0; 136 }
BZOJ 4397 [Usaco2015 dec]Breed Counting
直接用前缀和不就水过了么= =
1 #include <cstdio> 2 3 using namespace std; 4 5 const size_t Max_N(100050); 6 7 void Get_Val(int &Ret) 8 { 9 Ret = 0; 10 char ch; 11 while ((ch = getchar()), (ch > '9' || ch < '0')) 12 ; 13 do 14 { 15 (Ret *= 10) += ch - '0'; 16 } 17 while ((ch = getchar()), (ch >= '0' && ch <= '9')); 18 } 19 20 int N; 21 int Q; 22 int Prefix[4][Max_N]; 23 24 void init() 25 { 26 int Value; 27 Get_Val(N), Get_Val(Q); 28 for (int i = 1;i <= N;++i) 29 { 30 Get_Val(Value); 31 Prefix[1][i] = Prefix[1][i - 1] + (Value == 1); 32 Prefix[2][i] = Prefix[2][i - 1] + (Value == 2); 33 Prefix[3][i] = Prefix[3][i - 1] + (Value == 3); 34 } 35 } 36 37 inline 38 int Query(const int &c, const int &a, const int &b) 39 { 40 return Prefix[c][b] - Prefix[c][a - 1]; 41 } 42 43 void work() 44 { 45 int a, b; 46 while (Q--) 47 { 48 Get_Val(a), Get_Val(b); 49 printf("%d %d %d\n", Query(1, a, b), Query(2, a, b), Query(3, a, b)); 50 } 51 } 52 53 int main() 54 { 55 init(); 56 work(); 57 return 0; 58 }
USACO的大多数题目是真心水= =