[BZOJ2959] Long distance running
Question Description
A school carried out the students loved the sun long-distance running activities. In order to "work for the motherland's health for 50 years", students have left the bedroom, leaving the classroom, leaving the laboratory, to the playground to participate in 3000 meters long-distance running movement. For a time the playground was bustling, crowds and unprecedented.
In order to allow students to better supervise themselves, the school introduced a swipe mechanism.
There are n locations in the school, with an integer of 1 to n indicating that there are several card machines at each location.
The following three types of events are available:
1. A runway connecting A and B locations was built.
2, a point of the number of credit card machine changed to B.
3, carried out a long-distance running. Ask a classmate to go from a, finally arrive B can swipe a maximum number of times. The specific requirements are as follows:
When a classmate arrives at a place, he can swipe the card on every card here. However, each card reader can only swipe once, even if multiple times to the same location can not be repeated credit card.
For safety reasons, each runway needs to be set in one direction, and the runway can only be used in one direction. The maximum number of times to swipe is in any set runway direction, according to any path from a location to B location can swipe the most times.
Input
The first line of input contains two positive integer n,m, representing the number of places and the number of operations.
The second line contains n non-negative integers, where number i is the number of the first card machine at the beginning of the first place.
Next there are m lines, each containing three non-negative integers p,a,b,p as the event type, and a-B is the two parameter of the event.
There were no runways between all the original locations.
Each row is separated by a space between the two numbers that are adjacent to each other. Indicates that the number of locations is between 1 and N, and the number of swipe machines per location is never more than 10000,p=1,2,3.
Output
The number of rows in the output equals the number of class 3rd events, and each row represents a class 3rd event. If there is a scenario in which the runway direction is set and the path can be reached, the output can be up to the number of cards. If a cannot reach B, then output-1.
Input example
9 toTen - - + - - - the -3 1 21 1 31 1 21 8 91 2 41 2 51 4 61 4 73 1 83 8 81 8 93 8 83 7 53 7 31 4 13 7 53 7 31 5 73 6 53 3 61 2 41 5 53 3 62 8 the3 8 82 9 the3 9 92 5 Max3 3 62 1 About3 3 6
Output example
-1-1 280280370380580
Data size and conventions
For 100% of the data, m<=5n, at any time, each location of the number of credit card machine is not more than 10000. n<=1.5x105
Exercises
Note that this topic has a dual connectivity component when it is possible to design a scheme to run through the entire two-connected components, so simple LCT maintenance can not be used to use the indentation.
The so-called indentation is a circle to shrink it to a point, the weight of the new point equals the sum of all the original node weights in the circle. It can be accomplished by traversing it again.
Make a = number of nodes in the loop, the complexity of each indentation is O (a), at the same time the total number of nodes of the graph is reduced (A-1) points, so the overall indentation time complexity is O (n), then the total time complexity is O (n + mlogn).
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <stack > #include <vector> #include <queue> #include <cstring> #include <string> #include <map > #include <set>using namespace std;const int buffersize = 1 << 16;char buffer[buffersize], *head, *TAIL;INL ine Char Getchar () {if (Head = = tail) {int L = fread (buffer, 1, buffersize, stdin); Tail = (Head = buffer) + L; } return *head++;} int read () {int x = 0, f = 1; char c = Getchar (); while (!isdigit (c)) {if (c = = '-') f =-1; c = Getchar ();} while (IsDigit (c)) {x = x * + C-' 0 '; c = Getchar ();} return x * f;} #define MAXN 150010#define maxm 750010#define oo 2147483647int N, q;int Pa[maxn], pc[maxn];int findset (int x) {return x = = Pa[x]? X:PA[X] = Findset (pa[x]); }int FINDC (int x) {return x = = Pc[x]? x:pc[x] = FINDC (Pc[x]);} int FA[MAXN], ch[maxn][2], SUMV[MAXN], VAL[MAXN], A[maxn];bool rev[maxn];boolIsRoot (int u) {return Ch[findc (Fa[u])][0]! = u && ch[findc (Fa[u])][1]! = u;} void maintain (int u) {int LC = Ch[u][0], rc = ch[u][1];sumv[u] = SUMV[LC] + val[u] + Sumv[rc];return;} void pushdown (int u) {int &LC = ch[u][0], &RC = Ch[u][1];if (Rev[u]) {Rev[u] = 0; Swap (LC, RC); REV[LC] ^= 1; rev[rc ] ^= 1;} return;} void rotate (int u) {int y = FINDC (fa[u]), z = FINDC (Fa[y]), L = 0, R = 1;if (ch[y][1] = = u) Swap (L, R); if (!isroot (y)) ch[z] [Ch[z][1]==y] = u;fa[u] = Z; Fa[y] = u; Fa[ch[u][r]] = y;ch[y][l] = Ch[u][r]; Ch[u][r] = Y;maintain (y); Maintain (U); return;} int S[MAXN], top;void splay (int u) {bool flag = 0; S[++top] = u;for (int t = u;!isroot (t); t = FINDC (fa[t])) s[++top] = FINDC (fa[t]); while (top) pushdown (s[top--]); if (flag) p Utchar (' \ n '), while (!isroot (U)) {int y = FINDC (fa[u]), z = FINDC (fa[y]), if (!isroot (y)) {if ((ch[y][0] = = u) ^ (Ch[z][0] = = y )) rotate (u); else rotate (y);} Rotate (u);} return;} void access (int u) {for (int t = 0; u; u = fa[u]) {u = FINDC (u); splay (U); ch[u][1]= t; Maintain (U); t = u;} return;} void Makeroot (int u) {access (U); splay (U); rev[u] ^= 1;return;} void link (int a, int b) {makeroot (a); fa[a] = B;return;} void Split (int a, int b) {makeroot (b); access (a); splay (a); return;} void Dfs (int u, int v) {if (!u) return;p ushdown (u);p c[u] = v;if (U = v) val[v] + = Val[u];d FS (ch[u][0], v); Dfs (ch[u][1], V ); ch[u][0] = ch[u][1] = 0;return;} int main () {n = read (), q = Read (), for (int i = 1; I <= n; i++) a[i] = Val[i] = Read (), pa[i] = pc[i] = I;while (q--) {in T P = Read (), a = Read (), B = Read (), if (p = = 1) {a = FINDC (a), B = Findc (b), if (a = = b) continue;int u = Findset (a), V = f Indset (b); if (U = v) Pa[v] = u, link (a, b); else {split (A, b); Dfs (A, a); maintain (a);}} if (p = = 2) {int c = FINDC (a); splay (c); Val[c] + b-a[a]; A[a] = B;maintain (c);} if (p = = 3) {a = FINDC (a), B = Findc (b), int u = Findset (a), V = findset (b), if (U = v) puts ("-1"), else split (A, B), printf (" %d\n ", Sumv[a]);}} return 0;}
[BZOJ2959] Long-distance running-new skill: lct+ necking ring