蓝题训练9.26P5787 【模板】线段树分治 / 二分图
P5787 【模板】线段树分治 / 二分图
Tag:略
题意:略
题解:线段树分治板子
参考代码
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const ll N = 1e5 + 7, M = 2e5 + 7;
ll n, m, k, u[M], v[M], fa[N<<1], sz[N<<1];
struct T {
ll l, r;
vector<ll> e;
} t[N<<2];
stack<pair<ll,ll>> s;
ll ls(ll x){
return x<<1;
}
ll rs(ll x){
return (x<<1)|1;
}
void build(ll p, ll l, ll r) {
t[p].l = l, t[p].r = r;
if (l == r) return;
ll mid=(l+r)/2;
build(ls(p), l, mid),
build(rs(p), mid + 1, r);
}
void ins(ll p, ll l, ll r, ll x) {
if (t[p].l >= l && t[p].r <= r) {
t[p].e.push_back(x);
return;
}
ll mid = (t[p].l + t[p].r) / 2;
if (l <= mid) ins(ls(p), l, r, x);
if (r > mid) ins(rs(p), l, r, x);
}
inline ll find(ll x) {
while (x != fa[x]) x = fa[x];
return x;
}
inline void merge(ll x, ll y) {
if (x == y) return;
if (sz[x] > sz[y]) swap(x, y);
s.push({x,sz[x]}), fa[x] = y, sz[y]+=sz[x];
}
void dfs(ll p, ll l, ll r) {
bool ok = 1;
ll o = s.size();
for (ll i = 0; i < t[p].e.size(); i++) {
ll x = t[p].e[i], z = find(u[x]), y = find(v[x]);
if (z == y) {
for (ll j = l; j <= r; j++) cout<<"No\n";
ok = 0;
break;
}
ll zz=find(u[x]+n),yy=find(v[x]+n);
merge(zz, y), merge(yy, z);
}
if (ok) {
ll mid=(l+r)/2;
if (l == r) cout<<"Yes\n";
else dfs(ls(p), l, mid), dfs(rs(p), mid + 1, r);
}
while (s.size() > o) {
sz[fa[s.top().first]] -= s.top().second;
fa[s.top().first] = s.top().first;
s.pop();
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>m>>k;
build(1,1,k);
for (int i = 1, l, r; i <= m; i++) {
cin>>u[i]>>v[i]>>l>>r;
if (l<r) ins(1,l + 1,r,i);
}
for (int i = 1; i <= 2*n; i++) fa[i] = i,sz[i]=1;//初始化
dfs(1, 1, k);
return 0;
}

浙公网安备 33010602011771号