题解 等你哈苏德
- 对于每个点被多少区间覆盖一类问题:将这些区间差分了试试?
将所有区间差分成 \([l, r+1)\) 的形式
发现这个 \(abs\leqslant 1\) 就很烦
可以在每个被奇数个区间覆盖的位置 \(i\) 放一个区间 \([i, i+1)\) 转化为覆盖每个位置的黑色区间数等于白色区间数
那么现在每个区间就只影响两个点
而限制是每个点连出的边一半是黑的一半是白的
那么将给每个边赋颜色转化为给每条边定向,即为要求每个点入度等于出度
于是问题变为混合图欧拉回路
可以 dinic 解决
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 200010
#define pb push_back
#define ll long long
#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n, m, k;
int l[N], r[N], w[N], uni[N], usiz;
namespace task1{
int cnt[55];
void solve() {
int lim=1<<m;
for (int s=0; s<lim; ++s) {
memset(cnt, 0, sizeof(cnt));
for (int i=1; i<=m; ++i)
if (s&(1<<(i-1))) {
if (w[i]==-1 || w[i]==1) {for (int j=l[i]; j<=r[i]; ++j) ++cnt[j];}
else goto jump;
}
else {
if (w[i]==-1 || w[i]==0) {for (int j=l[i]; j<=r[i]; ++j) --cnt[j];}
else goto jump;
}
for (int i=1; i<=usiz; ++i) if (abs(cnt[i])>1) goto jump;
for (int i=0; i<m; ++i) printf((s&(1<<i))?"1 ":"0 ");
printf("\n"); exit(0);
jump: ;
}
puts("-1");
}
}
namespace task{
vector<int> to[N];
int sum[N], in[N], out[N], lim;
int head[N], dep[N], cur[N], s, t, ans, flow, ecnt=1;
struct edge{int from, to, next, val, id;}e[N<<1];
inline void add(int s, int t, int w, int id) {e[++ecnt]={s, t, head[s], w, id}; head[s]=ecnt;}
bool bfs(int s, int t) {
memset(dep, 0, sizeof(dep));
queue<int> q;
cur[s]=head[s]; dep[s]=1;
q.push(s);
while (q.size()) {
int u=q.front(); q.pop();
for (int i=head[u],v; ~i; i=e[i].next) {
v = e[i].to;
if (e[i].val && !dep[v]) {
dep[v]=dep[u]+1;
cur[v]=head[v];
if (v==t) return 1;
q.push(v);
}
}
}
return 0;
}
int dfs(int u, int in) {
if (u==t||!in) return in;
int rest=in, tem;
for (int i=cur[u],v; ~i; cur[u]=i=e[i].next) {
v = e[i].to;
if (e[i].val && dep[v]==dep[u]+1) {
tem=dfs(v, min(rest, e[i].val));
if (!tem) dep[v]=0;
e[i].val-=tem;
e[i^1].val+=tem;
rest-=tem;
if (!rest) break;
}
}
return in-rest;
}
void solve() {
memset(head, -1, sizeof(head)); k=m;
for (int i=1; i<=m; ++i) ++sum[l[i]], --sum[r[i]];
for (int i=1; i<=n; ++i) if ((sum[i]+=sum[i-1])&1)
++m, l[m]=i, r[m]=i+1, ++sum[i], --sum[r[m]], w[m]=-1;
// cout<<"sum: "; for (int i=1; i<=n; ++i) cout<<sum[i]<<' '; cout<<endl;
// cout<<"---lim---"<<endl;
// for (int i=1; i<=m; ++i) cout<<l[i]<<' '<<r[i]<<endl;
for (int i=1; i<=m; ++i)
if (w[i]==1) ++out[l[i]], ++in[r[i]], to[l[i]].pb(r[i]);
else if (w[i]==0) ++in[l[i]], ++out[r[i]], to[r[i]].pb(l[i]);
else ++out[l[i]], ++in[r[i]], add(l[i], r[i], 1, i), add(r[i], l[i], 0, i);
s=n+1, t=n+2; lim=ecnt;
// cout<<"in: "; for (int i=1; i<=n; ++i) cout<<in[i]<<' '; cout<<endl;
// cout<<"out: "; for (int i=1; i<=n; ++i) cout<<out[i]<<' '; cout<<endl;
for (int i=1; i<=n; ++i) {
if ((in[i]^out[i])&1) {puts("-1"); exit(0);}
if (in[i]>out[i]) add(i, t, (in[i]-out[i])>>1, 0), add(t, i, 0, 0);
if (in[i]<out[i]) add(s, i, (out[i]-in[i])>>1, 0), add(i, s, 0, 0), flow+=(out[i]-in[i])>>1;
}
while (bfs(s, t)) ans+=dfs(s, INF);
// cout<<"flow: "<<ans<<' '<<flow<<endl;
if (ans!=flow) {puts("-1"); exit(0);}
for (int i=2; i<=lim; i+=2) {
int u=e[i].from, v=e[i].to;
if (!e[i].val) to[v].pb(u), --in[v], --out[u], ++out[v], ++in[u], w[e[i].id]=0;
else to[u].pb(v), w[e[i].id]=1;
}
// cout<<"in: "; for (int i=1; i<=n; ++i) cout<<in[i]<<' '; cout<<endl;
// cout<<"out: "; for (int i=1; i<=n; ++i) cout<<out[i]<<' '; cout<<endl;
for (int i=1; i<=n; ++i) assert(in[i]==out[i]);
for (int i=1; i<=k; ++i) printf("%lld ", w[i]);
printf("\n");
}
}
signed main()
{
freopen("wait.in", "r", stdin);
freopen("wait.out", "w", stdout);
m=read(); n=read();
for (int i=1; i<=m; ++i) {l[i]=read(); r[i]=read()+1; w[i]=read();}
for (int i=1; i<=m; ++i) uni[++usiz]=l[i], uni[++usiz]=r[i];
sort(uni+1, uni+usiz+1);
usiz=unique(uni+1, uni+usiz+1)-uni-1;
n=usiz+1;
for (int i=1; i<=m; ++i) l[i]=lower_bound(uni+1, uni+usiz+1, l[i])-uni, r[i]=lower_bound(uni+1, uni+usiz+1, r[i])-uni;
task::solve();
return 0;
}