CF1697F
考虑 2-SAT,如果设 \((i,j,0/1)\) 表示 \(a_i\) 是否等于 \(j\) 则需要 \((i,1,1),\dots,(i,k,1)\) 中某一个被选,2-SAT 很难处理,于是设 \((i,j,0/1)\) 表示 \(a_i\) 是否大于等于 \(j\),最后找任意一个合法的即可。
由于边界上有可能会出现问题,所以我们可以加上 \(0\) 和 \(k+1\) 来方便操作。
1.本身含义
\((i,j,1)\rightarrow(i,j-1,1),(i,j-1,0)\rightarrow(i,j,0),(i,0,0)\rightarrow(i,0,1),(i,1,0)\rightarrow(i,1,1),(i,k+1,1)\rightarrow(i,k+1,0)\)
2.单调要求
\((i,j,1)\rightarrow(i+1,j,1),(i+1,j,0)\rightarrow(i,j,0)\)
3.\(a_i\neq j\)
若 \(j=k\),则 \((i,j,1)\rightarrow(i,j,0)\)
否则,\((i,j,1)\rightarrow(i,j+1,1),(i,j+1,0)\rightarrow(i,j,0)\)
4.\(a_i+a_j\le x\)
若 \(a_i\ge w\),则 \(a_j\le x-w\)。
若 \(v\le w,a_j\le x-w\),则 \(a_j\le x-v\)。
所以只需要考虑 \(a_j\le x-w\)。
于是 \(x-w\ge k\) 时直接忽略,\(1\le x-w\) 时 \((i,w,1)\rightarrow(j,x-w+1,0)\),否则类似第 3 类操作。
反向同理。
5.\(a_i+a_j\ge x\)
若 \(a_i\le w\),则 \(a_j\ge x-w\)。
若 \(v\ge w,a_j\ge x-w\),则 \(a_j\ge x-v\)。
所以只需要考虑 \(a_j\ge x-w\).
于是 \(x-w\le 1\) 时直接忽略,\(x-w\le k\) 时 \((i,w+1,0)\rightarrow(j,x-w,1)\) ,否则类似第 3 类操作。
反向同理。
#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define per(i,l,r) for(int i=(r);i>=(l);i--)
#define pb push_back
#define clr clear
using namespace std;
const int N=1e6+5;
int n,m,k;
int f(int x,int y,int z){
return n*(k+2)*z+(x-1)*(k+2)+(y+1);
}
vector<int>g[N];
void makeneq(int pos,int val){
if(1<=val&&val<=k){
g[f(pos,val,1)].pb(f(pos,val+1,1));
g[f(pos,val+1,0)].pb(f(pos,val,0));
}
}
int dfn[N],low[N],Tim;
int stk[N],top;
bitset<N>mk;
int col[N],idx;
void tarjan(int u){
dfn[u]=low[u]=++Tim;
stk[++top]=u;
mk[u]=1;
for(auto v:g[u]){
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(mk[v]){
low[u]=min(low[u],low[v]);
}
}
if(dfn[u]==low[u]){
idx++;
while(stk[top]!=u){
col[stk[top]]=idx;
mk[stk[top]]=0;
top--;
}
col[u]=idx;
mk[u]=0;
top--;
}
}
bool cmp(int x,int y){
return x>y;
}
void slv(){
scanf("%d %d %d",&n,&m,&k);
int nds=f(n,k+1,1);
rep(i,1,nds){
g[i].clr();
}
rep(i,1,n){
rep(j,0,k){
g[f(i,j,0)].pb(f(i,j+1,0));
g[f(i,j+1,1)].pb(f(i,j,1));
}
g[f(i,0,0)].pb(f(i,0,1));
g[f(i,1,0)].pb(f(i,1,1));
g[f(i,k+1,1)].pb(f(i,k+1,0));
}
rep(i,1,n-1){
rep(j,1,k){
g[f(i,j,1)].pb(f(i+1,j,1));
g[f(i+1,j,0)].pb(f(i,j,0));
}
}
while(m--){
int op;
scanf("%d",&op);
if(op==1){
int pos,val;
scanf("%d %d",&pos,&val);
makeneq(pos,val);
}
if(op==2){
int x,y,val;
scanf("%d %d %d",&x,&y,&val);
rep(w,1,k){
if(w>=val){
makeneq(x,w);
}
else if(w+k>val){
g[f(x,w,1)].pb(f(y,val-w+1,0));
g[f(y,val-w+1,1)].pb(f(x,w,0));
}
}
swap(x,y);
rep(w,1,k){
if(w>=val){
makeneq(x,w);
}
else if(w+k>val){
g[f(x,w,1)].pb(f(y,val-w+1,0));
g[f(y,val-w+1,1)].pb(f(x,w,0));
}
}
}
if(op==3){
int x,y,val;
scanf("%d %d %d",&x,&y,&val);
rep(w,1,k){
if(w+k<val){
makeneq(x,w);
}
else if(w<val-1){
g[f(x,w+1,0)].pb(f(y,val-w,1));
g[f(y,val-w,0)].pb(f(x,w+1,1));
}
}
swap(x,y);
rep(w,1,k){
if(w+k<val){
makeneq(x,w);
}
else if(w<val-1){
g[f(x,w+1,0)].pb(f(y,val-w,1));
g[f(y,val-w,0)].pb(f(x,w+1,1));
}
}
}
}
Tim=0;
mk=0;
idx=0;
rep(i,1,nds){
dfn[i]=0;
low[i]=0;
sort(g[i].begin(),g[i].end(),cmp);
}
per(i,1,nds){
if(!dfn[i]){
tarjan(i);
}
}
rep(i,1,n){
bool fd=0;
rep(j,1,k){
if(col[f(i,j,0)]==col[f(i,j,1)]){
printf("-1\n");
return ;
}
if(col[f(i,j,1)]<col[f(i,j,0)]){
fd=1;
}
}
if(!fd){
printf("-1\n");
return ;
}
}
rep(i,1,n){
per(j,1,k){
if(col[f(i,j,1)]<col[f(i,j,0)]){
printf("%d ",j);
break;
}
}
}
putchar('\n');
}
int main(){
int T=1;
scanf("%d",&T);
while(T--)slv();
return 0;
}

浙公网安备 33010602011771号