Title Description
Began \ (n-\) points, this now \ (n-\) points were \ (m \) operations, for the first \ (I \) operations (from \ (1 \) numbering) has possible three cases:
\ (The Add \) ab &: indicates \ (A \) between even a $ b $ length \ (I \) side (note, i is the operation number). Ensure \ (1 ≤ a, b≤n \) .
\ (The Delete \) k: delete the current figure represents the right side of the biggest \ (k \) edges. K guarantee that no more than the current number of edges in the graph.
\ (The Return \) : indicates undoes \ (i-1 \) operations. Guarantee \ (1 \) operations is not \ (the Return \) and the first \ (i-1 \) times than \ (the Return \) operation.
Please tell after each operation \ (DZY \) minimum spanning tree right edge of the current map and. If the output does not exist, the minimum spanning tree \ (0 \) .
Input
The first line of two positive integers \ (n-, m \) . He expressed \ (n-\) points \ (m \) operations.
Next \ (m \) lines each describing one operation.
Test point number | \(n\) | \(m\) | other |
---|---|---|---|
1 | \(n≤10^3\) | \(m≤10^3\) | Only \ (Add \) operations |
2 | \(n≤10^3\) | \(m≤10^3\) | |
3 | \(n≤10^3\) | \(m≤10^3\) | |
4 | \(n≤2×10^5\) | \(m≤2×10^5\) | Only \ (Add \) operations |
5 | \(n≤3×10^5\) | \(m≤5×10^5\) | Only \ (Add \) operations |
6 | \(n≤2×10^5\) | \(m≤2×10^5\) | No \ (Return \) operations |
7 | \(n≤3×10^5\) | \(m≤5×10^5\) | No \ (Return \) operations |
8 | \(n≤2×10^5\) | \(m≤2×10^5\) | |
9 | \(n≤2×10^5\) | \(m≤2×10^5\) | |
10 | \(n≤3×10^5\) | \(m≤5×10^5\) |
Output
For each operation the current output line represents an integer minimum spanning tree, and the right side.
Sample Input
2 2
Add 1 2
Return
5 10
Add 2 1
Add 3 2
Add 4 2
Add 5 2
Add 2 3
Return
Delete 1
Add 2 3
Add 5 2
Return
Sample Output
1
0
0
0
0
10
10
10
0
0
15
0
A algorithm:
\ (1-3 \) No. violence each test point directly minimum spanning tree, time complexity \ (O (m * n ^ 2α (n)) \) Score \ (30 \) .
Algorithms II:
Secondly, \ (4-5 \) number of test points only \ (Add \) test point operations can be found, because the edge weights are cumulative .
Thus, once the minimum spanning tree configuration, it will not change , the direct method according to each addition and check doing set.
Time complexity \ (O (Na (n-)) \) , a combinatorial algorithm, the score \ (50 \) .
Algorithms III:
We have found that operation of the operation and processing, on the main side of the deletion in the maintenance of several communication block .
So, how do retractable disjoint-set it?
Persistable disjoint-set, Of course, according to the rank of a merger of disjoint-set ! !
So, with regard to the operation and border erase the plus side we have been resolved. . .
The main problem in \ (return \) on the operation.
Speaking of the title, a \ (return \) before the operation of the operation can not be \ (return \) .
In other words, if the first \ (i \) operations for the \ (return \) operation, then the first \ (i \) answers the operations and \ (i-2 \) operate the same answer, the same time, the first \ (i-1 \) operations are not performed .
So, for a \ (Add \) or \ (Delete \) operation, we only care about the next one is not operating with a \ (return \) on the line.
So, let's offline operation.
For the current operation is \ (Add \) or \ (Delete \) then look in one operation, if it is \ (return \) direct execution.
Otherwise, after performing the operation able to save the answer, then withdraw operations.
Time complexity \ (O (n-log_n *) \) , the score \ (100 \) .
code show as below
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define u64 unsigned long long
#define u32 unsigned int
#define reg register
#define Raed Read
#define debug(x) cerr<<#x<<" = "<<x<<endl;
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
#define erep(i,x) for(reg int i=Head[x]; i; i=Nxt[i])
inline int Read() {
int res = 0, f = 1;
char c;
while (c = getchar(), c < 48 || c > 57)if (c == '-')f = 0;
do res = (res << 3) + (res << 1) + (c ^ 48);
while (c = getchar(), c >= 48 && c <= 57);
return f ? res : -res;
}
template<class T>inline bool Min(T &a, T const&b) {
return a > b ? a = b, 1 : 0;
}
template<class T>inline bool Max(T &a, T const&b) {
return a < b ? a = b, 1 : 0;
}
const int N=5e5+5;
bool MOP1;
int n,m;
struct node {
int op,a,b;
} Q[N];
struct T3Add {
int Fa[N];
int find(int x) {
return Fa[x]==x?Fa[x]:Fa[x]=find(Fa[x]);
}
inline void solve(void) {
rep(i,1,n)Fa[i]=i;
int tot=0,Ans=0;
rep(i,1,m) {
if(tot==n-1) {
printf("%lld\n",Ans);
continue;
}
int a=find(Q[i].a),b=find(Q[i].b);
if(a!=b) {
tot++,Ans+=i;
Fa[a]=b;
}
if(tot<n-1)puts("0");
else printf("%lld\n",Ans);
}
}
} PAdd;
struct T330 {
struct edge {
int a,b,c;
} Edge[N];
int Fa[N];
int find(int x) {
return Fa[x]==x?Fa[x]:Fa[x]=find(Fa[x]);
}
inline void solve(void) {
int tot=0,top=0;
rep(i,1,m) {
int op=Q[i].op;
if(op==1)Edge[++top]=(edge)<%Q[i].a,Q[i].b,i%>;
if(op==2)top-=Q[i].a;
if(op==3) {
if(Q[i-1].op==1)top--;
else top+=Q[i-1].a;
}
int Ans=0,res=0;
rep(j,1,n)Fa[j]=j;
rep(j,1,top) {
int a=find(Edge[j].a),b=find(Edge[j].b);
if(a==b)continue;
res++,Ans+=Edge[j].c,Fa[a]=b;
}
if(res!=n-1)Ans=0;
printf("%lld\n",Ans);
}
}
} P30;
struct T3Ac {
int Fa[N],dep[N],Ans[N];
struct edge {
int a,b;
} Edge[N];
int find(int x) {
return Fa[x]==x?Fa[x]:find(Fa[x]);
}
int stack[N];
inline void solve(void) {
int cnt=0,tot=0,top=0;
rep(i,1,n)Fa[i]=i;
rep(i,1,m) {
int op=Q[i].op;
if(op==1) {
int a=find(Q[i].a),b=find(Q[i].b);
if(a!=b)cnt++,tot+=i;
if(cnt==n-1)Ans[i]=tot;
else Ans[i]=Ans[i-1];
if(Q[i+1].op==3) {
Ans[i+1]=Ans[i-1];
if(a!=b)cnt--,tot-=i;
} else {
stack[++top]=i;
if(a!=b) {
if(dep[a]>dep[b])swap(a,b);
Fa[a]=b,Max(dep[b],dep[a]+1);
Edge[i].a=a,Edge[i].b=b;
}
}
}
if(op==2) {
Ans[i]=Ans[stack[top-Q[i].a]];
if(Q[i+1].op==3)Ans[i+1]=Ans[i-1];
else {
int k=Q[i].a;
rep(j,1,k) {
int Id=stack[top--],A=Edge[Id].a;
if(!A)continue;
Fa[A]=A;
cnt--,tot-=Id;
}
}
}
printf("%lld\n",Ans[i]);
}
}
} P100;
char S[15];
bool MOP2;
inline void _main(void) {
n=Raed(),m=Read();
int f=0;
rep(i,1,m) {
scanf("%s",S);
if(S[0]!='A')f=1;
if(S[0]=='A')Q[i]=(node)<%1,Read(),Read()%>;
if(S[0]=='D')Q[i]=(node)<%2,Read(),0%>;
if(S[0]=='R')Q[i]=(node)<%3,0,0%>;
}
if(!f)PAdd.solve();
else if(n<=1000&&m<=1000)P30.solve();
else P100.solve();
}
signed main() {
#define offline1
#ifdef offline
freopen("graph.in", "r", stdin);
freopen("graph.out", "w", stdout);
_main();
fclose(stdin);
fclose(stdout);
#else
_main();
#endif
return 0;
}