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;
}

浙公网安备 33010602011771号