Constrained Sums

Constrained Sums

考虑记 \(F_{i,j} = [X_i \geq j]\),接下来推导出一些性质:

  • \(F_{i,0} = 1\)

  • \(F_{i,M+1} = 0\)

  • \(F_{i,j} = 0 \to F_{i,j+1} = 0\)

  • \(F_{i,j}=1 \to F_{i,j-1}=1\)

据此,我们定义 \(G(x) = \min(M+1,\max(0,x))\)

这两点根据 \(F\) 的定义都是显然的,接下来考虑区间限制,我们需要保证:

  • \(F_{A_i,j} = 0 \to F_{B_i,G(L_i - j + 1)} = 1\)

考虑 \(X_{A_i} < j\),而 \(X_{A_i} + X_{B_i} \geq L_i\)

也就是说,\(X_{B_i} \geq L_i - X_{A_i} \geq L_i - j + 1\)

  • \(F_{A_i,j} = 1 \to F_{B_i,G(R_i - j + 1)} = 0\)

考虑 \(X_{A_i} \geq j\),而 \(X_{A_i} + X_{B_i} \leq R_i\)

也就是说,\(X_{B_i} \leq R_i - X_{A_i} \leq R_i - j\)

化为一般的形式,\(X_{B_i} \geq R_i - j + 1\) 为假。

接下来解决 2-SAT 问题即可,时间复杂度 \(O((N+Q)M)\)

#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
using namespace std;
const int N=10000+10,M=100+10;
int n,m,q,id[N][M],tot_node;
vector<int> G[2*N*M];
int GG(int num){
	return min(m+1,max(0,num));
}
stack<int> stk;
bool in_stack[2*N*M];
int dfn[2*N*M],low[2*N*M],col[2*N*M],tot_dfn,tot_col;
void tarjan(int u){
	dfn[u]=low[u]=++tot_dfn;
	stk.push(u);
	in_stack[u]=true;
	for(int i=0;i<G[u].size();i++){
		int v=G[u][i];
		if(!dfn[v]){
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(in_stack[v]){
			low[u]=min(low[u],dfn[v]);
		}
	}
	if(low[u]==dfn[u]){
		tot_col++;
		while(!stk.empty()){
			int pre=stk.top();
			stk.pop();
			col[pre]=tot_col;
			in_stack[pre]=false;
			if(u==pre){
				break;
			}
		}
	}
}
int main(){
	scanf("%d %d %d",&n,&m,&q);
	for(int i=1;i<=n;i++){
		for(int j=0;j<=m+1;j++){
			id[i][j]=++tot_node;
		}
	}
	for(int i=1;i<=n;i++){
		G[id[i][0]].push_back(id[i][0]+tot_node);
		G[id[i][m+1]+tot_node].push_back(id[i][m+1]);
		for(int j=0;j<=m;j++){
			G[id[i][j]].push_back(id[i][j+1]);
			G[id[i][j+1]+tot_node].push_back(id[i][j]+tot_node);
		}
		for(int j=1;j<=m+1;j++){
			G[id[i][j]+tot_node].push_back(id[i][j-1]+tot_node);
			G[id[i][j-1]].push_back(id[i][j]);
		}
	}
	while(q--){
		int A,B,L,R;
		scanf("%d %d %d %d",&A,&B,&L,&R);
		for(int i=0;i<=m;i++){
			G[id[A][i]].push_back(id[B][GG(L-i+1)]+tot_node);
			G[id[B][GG(L-i+1)]].push_back(id[A][i]+tot_node);
			G[id[B][i]].push_back(id[A][GG(L-i+1)]+tot_node);
			G[id[A][GG(L-i+1)]].push_back(id[B][i]+tot_node);
			G[id[A][i]+tot_node].push_back(id[B][GG(R-i+1)]);
			G[id[B][GG(R-i+1)]+tot_node].push_back(id[A][i]);
			G[id[B][i]+tot_node].push_back(id[A][GG(R-i+1)]);
			G[id[A][GG(R-i+1)]+tot_node].push_back(id[B][i]);
		}
	}
	for(int i=1;i<=2*tot_node;i++){
		if(!dfn[i]){
			tarjan(i);
		}
	}
	for(int i=1;i<=tot_node;i++){
		if(col[i]==col[i+tot_node]){
			printf("-1\n");
			return 0;
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=m;j>=0;j--){
			if(col[id[i][j]]>col[id[i][j]+tot_node]){
				printf("%d ",j);
				break;
			}
		}
	}
	return 0;
}
posted @ 2026-08-15 16:28  Oken喵~  阅读(4)  评论(0)    收藏  举报