Hello Codeforces!
problem link: Connect and Disconnect
my buggy solution:
Spoiler
/**
* “Experience is the name everyone gives to their mistakes.” – Oscar Wilde
*
* author : prodipdatta7
* created : Thursday 26-March, 2020 08:55:24 AM
**/
//#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stack>
#include <queue>
#include <deque>
#include <iterator>
#include <bitset>
#include <assert.h>
#include <new>
#include <sstream>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
// #pragma GCC optimize("Ofast")
// #pragma GCC target("avx,avx2,fma")
// #pragma GCC optimize("unroll-loops")
using namespace std ;
using namespace __gnu_pbds ;
#define ll long long
#define ld long double
#define ull unsigned long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vll vector<ll>
#define vvi vector<vector<int>>
#define debug(x) cerr << #x << " = " << x << '\n' ;
#define rep(i,b,e) for(__typeof(e) i = (b) ; i != (e + 1) - 2 * ((b) > (e)) ; i += 1 - 2 * ((b) > (e)))
#define all(x) x.begin() , x.end()
#define rall(x) x.rbegin() , x.rend()
#define sz(x) (int)x.size()
#define ff first
#define ss second
#define pb push_back
#define eb emplace_back
#define mem(a) memset(a , 0 ,sizeof a)
#define memn(a) memset(a , -1 ,sizeof a)
#define fread freopen("connect.in","r",stdin)
#define fwrite freopen("connect.out","w",stdout)
#define TN typename
typedef tree <int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update > ordered_set;
typedef tree <int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update > ordered_multiset;
/*
Note : There is a problem with erase() function in ordered_multiset (for less_equal<int> tag).
lower_bound() works as upper_bound() and vice-versa.
Be careful to use.
i) find_by_order(k) : kth smallest element counting from 0 .
ii) order_of_key(k) : number of elements strictly smaller than k.
*/
/*###############-> Input Section <-###############*/
template <TN T> inline void Int(T &a) {
bool minus = false; a = 0; char ch = getchar();
while (true) { if (ch == '-' or (ch >= '0' && ch <= '9')) break; ch = getchar(); }
if (ch == '-') minus = true; else a = ch - '0';
while (true) { ch = getchar(); if (ch < '0' || ch > '9') break; a = a * 10 + (ch - '0'); }
if (minus)a *= -1 ;
}
template < TN T, TN T1 > inline void Int(T &a, T1 &b) {Int(a), Int(b) ;}
template < TN T, TN T1, TN T2 > inline void Int(T &a, T1 &b, T2 &c) {Int(a, b), Int(c) ;}
template < TN T, TN T1, TN T2, TN T3 > inline void Int(T &a, T1 &b, T2 &c, T3 &d) {Int(a, b), Int(c, d) ;}
template < TN T, TN T1, TN T2, TN T3, TN T4> inline void Int(T &a, T1 &b, T2 &c, T3 &d, T4 &e) {Int(a, b), Int(c, d, e) ;}
/*###############-> Debugger <-###############*/
#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
void err(istream_iterator<string> it) {cout << endl ;}
template<TN T, TN... Args>
void err(istream_iterator<string> it, T a, Args... args) {
cerr << *it << " = " << a << ' ' ;
err(++it, args...);
}
/******************************************
#Rows are numbered from top to bottom.
#Columns are numbered from left to right.
Moves : L, U, R, D, LU, RU, RD, LD.
******************************************/
int dx[8] = {0, -1, 0, 1, -1, -1, 1, 1} ;
int dy[8] = {-1, 0, 1, 0, -1, 1, 1, -1} ;
/*###############-> Constraints <-###############*/
const int N = (int)3e5 + 5 ;
const int maxN = (int)1e6 + 6 ;
const ll Mod = (ll)1e9 + 7 ;
const int inf = (int)2e9 ;
const ll Inf = (ll)1e18 ;
const int mod = (int)1e9 + 7 ;
inline int add(int a, int b, int mod) {a += b ; return a >= mod ? a - mod : a ;}
inline int sub(int a, int b, int mod) {a -= b ; return a < 0 ? a + mod : a ;}
inline int mul(int a, int b, int mod) {return (ll)a * b % mod ;}
/*...... ! Code starts from here ! ......*/
struct dsu_save{
int v, rnkv, u, rnku ;
dsu_save() {}
dsu_save(int _v, int _rnkv, int _u, int _rnku)
: v(_v), rnkv(_rnkv), u(_u), rnku(_rnku) {}
} ;
struct dsu_with_rollbacks{
vector < int > p, rnk ;
int comps ;
stack < dsu_save > op ;
dsu_with_rollbacks() {}
dsu_with_rollbacks(int n){
p.resize(n + 1) ;
rnk.resize(n + 1) ;
comps = n ;
for(int i = 0 ; i <= n ; ++i)
p[i] = i, rnk[i] = 0 ;
}
int find_set(int s){
return p[s] = (p[s] == s) ? s : find_set(p[s]) ;
}
bool unite(int v, int u){
v = find_set(v) ;
u = find_set(u) ;
if(u == v)
return false ;
--comps ;
if(rnk[v] > rnk[u])
swap(v, u) ;
op.push(dsu_save(v, rnk[v], u, rnk[u])) ;
p[v] = u ;
if(rnk[v] == rnk[u])
++rnk[u] ;
return true ;
}
void rollback(){
if(op.empty())
return ;
dsu_save x = op.top() ;
op.pop() ;
++comps ;
p[x.v] = x.v ;
rnk[x.v] = x.rnkv ;
p[x.u] = x.u ;
rnk[x.u] = x.rnku ;
}
} ;
struct query {
int v, u ;
bool united ;
query(int _v = 0, int _u = 0)
: v(_v), u(_u) {}
} ;
struct QueryTree{
vector < vector < query > > t ;
dsu_with_rollbacks dsu ;
int T ; // T = number of query ;
QueryTree() {}
QueryTree(int _T, int n): T(_T) {
dsu = dsu_with_rollbacks(n) ; // n = number of nodes in the graph
t.resize((4 * T) + 5) ;
}
void add_to_tree(int i, int b, int e, int l, int r, query& q){
if(e < l or b > r)return ;
if(l <= b and e <= r){
t[i].push_back(q) ;
return ;
}
int mid = (b + e) >> 1 ;
add_to_tree(i << 1, b, mid, l, r, q) ;
add_to_tree(i << 1 | 1, mid + 1, e, l, r, q) ;
}
void add_query(query q, int l, int r){
add_to_tree(1, 1, T, l, r, q) ;
//error(q.v, q.u, l, r)
}
void dfs(int i, int b, int e, vector < int > &ans){
for(query &q : t[i]){
q.united = dsu.unite(q.v, q.u) ;
}
if(b == e)
ans[b] = dsu.comps ;
else {
int mid = (b + e) >> 1 ;
dfs(i << 1, b, mid, ans) ;
dfs(i << 1 | 1, mid + 1, e, ans) ;
}
for(query q : t[i]){
if(q.united)
dsu.rollback() ;
}
}
vector < int > solve(){
vector < int > ans(T + 1) ;
dfs(1, 1, T, ans) ;
return ans ;
}
} ;
struct offline{
query enroll ;
int l, r ;
offline(int _u = 0, int _v = 0, int _l = 0, int _r = 0)
: enroll(query(_u, _v)), l(_l), r(_r) {}
} ;
vector < offline > store ;
map < pii, int > rng ;
int main() {
// ios_base::sync_with_stdio(false) ;
// cin.tie(NULL) ; cout.tie(NULL) ;
fread ;
fwrite ;
int test = 1 , tc = 0 ;
//Int(test) ;
while (test--) {
int n, k, x, y ; Int(n, k) ;
QueryTree QT(k + 1, n) ;
char c[2] ;
vector < int > pos ;
for(int i = 1 ; i <= k ; ++i){
scanf("%s",c) ;
if(c[0] == '?'){
pos.push_back(i) ;
continue ;
}
Int(x, y) ;
if(x > y)swap(x, y) ;
pii p = make_pair(x, y) ;
if(c[0] == '+'){
rng[p] = i ;
}
else if(c[0] == '-'){
int L = rng[p] ;
store.push_back(offline(x, y, L, i - 1)) ;
auto it = rng.find(p) ;
if(it != rng.end())rng.erase(it) ;
}
}
for(auto i : rng){
store.push_back(offline(i.ff.ff, i.ff.ss, i.ss, k)) ;
}
for(offline i : store){
QT.add_query(i.enroll, i.l, i.r) ;
}
vector < int > ans = QT.solve() ;
for(int i : pos){
cout << ans[i] << '\n' ;
}
}
return 0 ;
}
I have read the tutorial from here and have tried to solve the problem linked above. But I'm getting WA on test 7. Can't find the bug of my code.
I need help to find out the bug.
please help me.
StayAtHome
TIA.