#include <cstdio> #include <iostream> #include <utility> #include <vector> using namespace std;
const int N = 2e5+10;
namespace dsu { int fa[N], siz[N], cnt; vector<pair<int,int>> opt; inline void init(int n) { for(int i = 1; i <= n; i++) fa[i] = i, siz[i] = 1; } inline int find(int x) { while(fa[x] != x) x = fa[x]; return x; } inline bool check(int x, int y) { return find(x) == find(y); } inline bool merge(int x, int y) { x = find(x), y = find(y); if(x == y) return false; if(siz[x] < siz[y]) swap(x, y); opt.push_back({x, y}); siz[x] += siz[y]; fa[y] = x; cnt--; return true; } inline void undo() { int x = opt.back().first; int y = opt.back().second; opt.pop_back(); siz[x] -= siz[y]; fa[y] = y; cnt++; } }
namespace tree { vector<int> opt[N*4]; int lim; void add(int ql, int qr, int id, int i = 1, int l = 1, int r = lim); void solve(int i = 1, int l = 1, int r = lim); }
int n, m, k, tp, q; int u[N], v[N]; int f[N];
int main() { read(n, m, k, tp); for(int i = 1; i <= m; i++) read(u[i], v[i]); f[m+1] = m+1; dsu::init(n); dsu::cnt = n; tree::lim = m; tree::solve(); read(q); unsigned int lans = 0; for(int i = 1, l, r; i <= q; i++) { read(l, r); if(tp == 1) { l = (l+lans)%m+1; r = (r+lans)%m+1; if(l > r) swap(l, r); } lans <<= 1; if(f[r] > l) print("Yes\n"), lans|=1; else print("No\n"); } }
namespace tree { #define ls (i<<1) #define rs (i<<1|1) #define lmid ((l+r)>>1) #define rmid ((l+r+2)>>1) inline void solve(int i, int l, int r) { int tot = 0; for(auto x : opt[i]) tot += dsu::merge(u[x], v[x]); if(l == r) { f[l] = f[l+1]; while(f[l] > 1) { tot += dsu::merge(u[f[l]-1], v[f[l]-1]); if(dsu::cnt <= k) break; f[l]--; if(f[l] < l) tree::add(f[l], l-1, f[l]); } } else { solve(rs, rmid, r); solve(ls, l, lmid); } while(tot --> 0) dsu::undo(); } void add(int ql, int qr, int id, int i, int l, int r) { if(ql <= l and r <= qr) return opt[i].push_back(id); if(ql <= lmid) add(ql, qr, id, ls, l, lmid); if(qr >= rmid) add(ql, qr, id, rs, rmid, r); } }
|