代码细节太多
先求出 一颗生成树 如果距离为奇数 那就满足 这一过程可以用lca 求解
其他情况下 如果a到b的路径上有一条边属于奇环 那么也符合
那么我们已经清楚如何取求解 剩下就是取维护每条边是否在 奇环上
可以 用差分 但是 这题因为要用到lca 就直接树链剖分维护了
#include
using namespace std;
//#define int long long
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
#define fi first
#define se second
#define pb push_back
#define inf 1<<62
#define endl "\n"
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define de_bug(x) cerr << #x << "=" << x << endl
#define all(a) a.begin(),a.end()
#define IOS std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fer(i,a,b) for(int i=a;i<=b;i++)
#define der(i,a,b) for(int i=a;i>=b;i--)
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
int n, m , k;
int id[N];
int top[N], fa[N], f[N], d[N], son[N], siz[N];
vi g[N];
int tot;
struct node {
int l, r;
int tag, sum;
} tr[N * 4];
void push_up(int i) {
tr[i].sum = tr[i * 2].sum + tr[i * 2 + 1].sum;
}
/*void push_down(int i) {
if(tr[i].tag) {
tr[i * 2].tag = tr[i].tag;
tr[i * 2 + 1].tag = tr[i].tag;
tr[i * 2].sum += tr[i].tag * (tr[i * 2].r - tr[i * 2].l + 1);
tr[i * 2 + 1].sum += tr[i].tag * (tr[i * 2 + 1].r - tr[i * 2 + 1].l + 1);
}
tr[i].tag = 0;
}*/
void pushdown(int i) {
//int mid = (tr[i].r - tr[i].l) >> 1;
if(tr[i].sum == (tr[i].r - tr[i].l + 1)) {
tr[i * 2].sum = tr[i * 2].r - tr[i * 2].l + 1;
tr[i * 2 + 1].sum = tr[i * 2 + 1].r - tr[i * 2 + 1].l + 1;
}
}
void build(int i, int l, int r) {
tr[i] = {l, r, 0, 0};
if(l == r) {
return ;
}
int mid = (l + r) >> 1;
build(i * 2, l, mid);
build(i * 2 + 1, mid + 1, r);
}
void change(int i, int l, int r, int val) {
if(l <= tr[i].l && tr[i].r <= r) {
// tr[i].tag += val;
tr[i].sum = tr[i].r - tr[i].l + 1;
return ;
}
pushdown(i);
int mid = (tr[i].l + tr[i].r) >> 1;
if(l <= mid) change(i * 2, l, r, val);
if(r > mid)change(i * 2 + 1, l, r, val);
push_up(i);
}
int query(int i, int l, int r) {
if(l <= tr[i].l && tr[i].r <= r) {
return tr[i].sum;
}
int mid = (tr[i].l + tr[i].r) >> 1;
pushdown(i);
int ans = 0;
if(l <= mid) ans += query(i * 2, l, r);
if(r > mid) ans += query(i * 2 + 1, l, r);
return ans;
}
int qry(int x, int y) {
int cnt = 0;
while(top[x] != top[y]) {
if(d[top[x]] < d[top[y]])swap(x, y);
cnt += query(1, id[top[x]], id[x]);
x = f[top[x]];
}
if(d[y] < d[x]) swap(x, y);
cnt += query(1, id[x], id[y]);
return cnt;
}
void upd(int x, int y) {
//if(x==5&&y==7)cout<<"/"<
while(top[x] != top[y]) {
if(d[top[x]] < d[top[y]])swap(x, y);
change(1, id[top[x]], id[x], 1);
x = f[top[x]];
}
if(d[x] > d[y])swap(x, y);
change(1, id[son[x]], id[y], 1);
}
void dfs1(int u, int fa) {
d[u] = d[fa] + 1;
f[u] = fa;
siz[u] = 1;
int ma = -1;
for(auto v : g[u]) {
if(d[v])continue;
dfs1(v, u);
siz[u] += siz[v];
if(ma < siz[v]) {
son[u] = v, ma = siz[v];
}
}
}
void dfs2(int u, int ff) {
id[u] = ++tot;
top[u] = ff;
if(!son[u])return;
dfs2(son[u], ff);
for(auto v : g[u]) {
if(v != son[u] && d[v] > d[u] && f[v] == u)dfs2(v, v);
}
}
void dfs3(int u) {
for(auto v : g[u]) {
if(v == f[u])continue;
if(f[v] == u)dfs3(v);
else if( d[v] > d[u] && ( !((d[u] - d[v]) & 1) )) upd(v, u);
}
}
void dfs4(int u) {
for(auto v : g[u]) {
if(v == f[u])continue;
if(f[v] == u)dfs4(v);
else if(d[v] > d[u])continue;
else if( (d[u] - d[v]) & 1) {
if(qry(v, u) - query(1, id[v], id[v]) > 0 ) {
upd(v, u);
}
}
}
}
int lca(int x, int y) {
while(top[x] != top[y]) {
if(d[top[x]] < d[top[y]])swap(x, y);
x = f[top[x]];
}
return d[x] < d[y] ? x : y;
}
int get_(int a, int b) {
return d[a] + d[b] - 2 * d[lca(a, b)];
}
int find1(int x) {
return fa[x] == x ? x : fa[x] = find1(fa[x]);
}
void merge(int a, int b) {
int x = find1(a);
int y = find1(b);
if(x == y)return ;
fa[x] = y;
}
void solve() {
cin >> n >> m;
fer(i, 1, n) {
fa[i] = i;
}
fer(i, 1, m) {
int a, b;
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
merge(a, b);
}
build(1, 1, n);
fer(i, 1, n) {
if(!d[i]) {
dfs1(i, 0);
dfs2(i, i);
dfs3(i);
dfs4(i);
}
}
int q;
cin >> q;
fer(i, 1, q) {
int a, b;
cin >> a >> b;
int LCA = lca(a, b);
if(find1(a) != find1(b))puts("No");
else {
if(get_(a, b) & 1)puts("Yes");
else if(qry(a, b) - query(1, id[LCA], id[LCA]) > 0) {
puts("Yes");
} else puts("No");
}
}
}
int main() {
IOS;
int _ = 1;
//cin>>_;
while( _-- )
solve();
}