Ah, CF is changing.
Question A: I wrote A binary question, question...
Question B: Simulation questions, water
Question C: After thinking for a long time, Shui Wang (a senior student) told me that it was DP and he knocked it out.
Dp [I] [j] indicates that the I character goes to the maximum weight of the j character
View Code
int dp[30][30];int max(int a,int b){ return a>b?a:b;}int main(){ int n,i,j,k; char s[15]; while(scanf("%d",&n)!=EOF) { memset(dp,0,sizeof(dp)); for(k=1;k<=n;k++) { scanf("%s",s); int len=strlen(s); for(i=0;i<26;i++) { if(dp[i][s[0]-'a']) dp[i][s[len-1]-'a']=max(dp[i][s[len-1]-'a'],dp[i][s[0]-'a']+len); } if(len>dp[s[0]-'a'][s[len-1]-'a']) dp[s[0]-'a'][s[len-1]-'a']=len; } int ans=0; for(i=0;i<26;i++) { if(dp[i][i]>ans) ans=dp[i][i]; } printf("%d\n",ans); } return 0;}
D:
Maintain a heap or a et from the right to the left.
E:
Question: give you a tree, and then give you some points. The data range is 10 W. For each point, the points in the simple path between the two points will be passed through once.
Finally, the number of times each edge is routed
This is the most amazing question. After the game, after a long time, I finally got the code from the big boys and finally got it on a dark night evening. I would like to mark my spirit of death, hehe
Search the tree first to obtain the timestamp and the depth of each point. The objective is to find the point-to-point LCA (recent common ancestor) and change the tree to a directed one.
Here is the core.
Record an array c [];
For a pair of vertices (u v), their LCA (u, v) = X
C [u] ++; c [v] ++; c [x] + = 2; that is, when a point is a point in a pair, add 1 to the tag array. If it is the closest common ancestor of two vertices, add 2
At first, I never understood what this would do. However, I had to work on group data, perform single-step debugging, and tune it for a long time. I finally figured out the magic of this tag array.
Okay, let's see the picture.
(The direction has been adjusted, with 1 as the root), now if there are two points (12, 14) (14, 15), then
C [12] = 1, c [14] = 2, c [15] = 1, la [7] = 2, la [3] = 2;
Then we started the second dfs and determined how many times each edge was processed mainly in the Backtracking process.
The corresponding information of the subtree node will be transmitted each time during backtracking, for example, from v back to u, first, we need to determine that several v sub-nodes will "rush" v through the edge between u-> v.
Of course, this number is definitely not the number marked in the subtree, because the LCA of a certain two points may also be in the subtree, and these two points will not come up, that is, it does not pass through the edge between u-v.
Therefore, an LCA can prevent two vertices in the subtree (that is, a certain pair of input vertices) from walking out of the subtree (this explains the step la [x] + = 2 ), in the program, it is represented as follows: after a point is traced back, the value of la [u] at this point is first subtracted, indicating that the number of points in la [u] is reduced, then, we can figure out the number of times the edge between u-> v passes through the process from v back to u. After backtracking, all the answers will be answered.
For example, the number on the left side of the red graph is the number of these sides (to facilitate the graph to only use these sides)
Traverse to 12 first and start to trace back to 6. edge [1] is passed once, edge [1] = 1; edge between 13 and 6 is not passed, so back to 6
A total of sum = 1 points come up, continue to 3, first subtract the value of 6 la [] (0), so, the edge between 6 and 3 can be obtained after several times.
Edge [4] = sum + c [6] c [6] is 0, so edge [4] = 1;
Tracing on the right:
14. 15 trace back to 7, edge [2] adds 2, edge [3] adds 1, sum = 3, and then traces 7 from 7 to 3, so first subtract the value of la [7]
In this case, sum = 1, which is equivalent to a point in the subtree of 7 that will come out and go through edge [5], so edge [5] = 1; continue to trace back ......
In this way, the complexity is the complexity of the LCA. The timestamp sequence of 2 * n * log (2 * n) records is 2 * n length.
My code
View Code
# Include <string. h> # include <stdio. h> # include <vector> # include <math. h> using namespace std; const int M = 100100; const double inf = 1e20; int min (int a, int B) {return a <B? A: B;} int n, k, tdfn, tot; int dp [20] [2 * M], vis [M]; int B [2 * M], LOG [2 * M], used [M], F [2 * M], pos [M], c [M], la [M]; vector <int> edge [M], eg [M]; int ans [M]; void rmq_init (int n, int num []) {int I, j; for (j = 1; j <= n; j ++) dp [0] [j] = num [j]; for (j = 1; j <= LOG [n]; j ++) {int limit = n + 1-(1 <j); for (I = 1; I <= limit; I ++) {int x = I + (1 <j> 1); dp [j] [I] = min (dp [J-1] [x], dp [J-1] [I]) ;}} int rmq (int l, int r, int num []) {int m = LOG [r-l + 1]; return mi N (dp [m] [l], dp [m] [r-(1 <m) + 1]);} void dfs (int s) {int I, t; used [s] = 1; int tmp = ++ tdfn; B [++ tot] = tmp; F [tmp] = s; pos [s] = tot; int sz = edge [s]. size (); for (I = 0; I <sz; I ++) {t = edge [s] [I]; if (used [t]) continue; dfs (t); B [++ tot] = tmp; // backtrack} used [s] = 0;} int lca (int a, int B) {if (pos [a]> pos [B]) swap (a, B); int ans = rmq (pos [a], pos [B], B ); return F [ans];} void init () {tdfn = 0; tot = 0; memset (used, 0, sizeof (used); dfs (1); rmq_init (tot, B);} int solve (int u, int edge_num) // core {int sum = 0; used [u] = 1; int sz = edge [u]. size (); for (int I = 0; I <sz; I ++) {int to = edge [u] [I]; if (used [to]) continue; sum + = solve (to, eg [u] [I]);} sum-= la [u]; if (edge_num) ans [edge_num] = sum + c [u]; return ans [edge_num];} int main () {int I, n, m, a, B, w; LOG [0] =-1; for (I = 1; I <2 * M; I ++) LOG [I] = LOG [I> 1] + 1; while (scanf ("% d", & n )! = EOF) {for (I = 0; I <= n; I ++) {edge [I]. clear (); c [I] = 0;} char str [5]; for (I = 1; I <n; I ++) {scanf ("% d", & a, & B); edge [a]. push_back (B); edge [B]. push_back (a); eg [a]. push_back (I); eg [B]. push_back (I);} init (); scanf ("% d", & k); while (k --) {scanf ("% d", &, & B); c [a] ++; c [B] ++; int x = lca (a, B); la [x] ++ = 2 ;} solve (1, 0); for (I = 1; I <n; I ++) printf ("% d", ans [I]); puts ("");} return 0 ;}