Submission #36576258
Source Code Expand
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<(int)n;i++)
#define per(i,a,n) for (int i=n;i-->(int)a;)
int read(){int r;scanf("%d",&r);return r;}
class TwoSat{
vector<int> low; // 能达到的最小的点
vector<int> dfn; // tarjan 用的深搜访问次序标识
stack<int> stk; // tarjan 用的stk
vector<int> res; // tarjan 结果
vector<vector<int> > p; // 所有点
int n;
void scc(int v) {
static int id = 0;
low[v] = dfn[v] = id++;
stk.push(v);
for(auto w:p[v]){
if(dfn[w] == -1){ // 未访问过
scc(w);
low[v] = min(low[v],low[w]);
} else if(res[w] == -1){ // 访问过但没有结果(在栈中)
low[v] = min(low[v],dfn[w]);
}
}
int u;
if(low[v] == dfn[v]) {
do{
res[u = stk.top()] = v;
stk.pop();
}while(u != v);
}
}
public:
TwoSat(int SZ):n(SZ){ // 点范围[0..SZ-1]
low = vector<int>(2*n,-1);
dfn = vector<int>(2*n,-1);
stk = {};
res = vector<int> (2*n,-1);
p = vector<vector<int> >(2*n);
}
bool calc(vector<bool> & ans){
rep(i,0,2*n) if(res[i]==-1)scc(i);
rep(i,0,n) if(res[i*2]==res[i*2+1])return false; // 同一个块的真假都在一个scc里
vector<int> revscc(2*n); // 互斥scc
rep(i,0,n) { // 每个点的true/false 状态互斥
revscc[res[i*2]] = res[i*2+1];
revscc[res[i*2+1]] = res[i*2];
}
vector<set<int> > scc2scc(2*n);
unordered_map<int,int> degree; // scc入度
rep(i,0,2*n) { // 跨scc的反向边, 做拓扑选择, (因为scc计算后,剩下的一定是偏序不会有环)
degree[res[i]] = 0;
for(auto j:p[i]) if(res[i]!=res[j]) scc2scc[res[j]].insert(res[i]); // i -> j 反向边
}
for(auto &s:scc2scc) for(auto t:s) degree[t]++;
vector<int> d0; // 入度为0
for(auto [v,d]: degree) if(!d) d0.push_back(v);
unordered_map<int,bool> sccpick; // scc 选/不选
rep(i,0,d0.size()) {
if(!sccpick.count(d0[i])){ // 没有计算过
// prinpick("pick %d, unpick %d\n",d0[i],revscc[d0[i]]);
sccpick[d0[i]] = true;
sccpick[revscc[d0[i]]] = false;
}
for(auto item:scc2scc[d0[i]]) if(!(--degree[item])) d0.push_back(item); // 更新入度排序
}
ans = vector<bool>(n);
rep(i,0,n) ans[i] = sccpick[res[i*2+1]];
return true;
}
void then(pair<int,bool> pi, pair<int,bool> pj){ // {i,true/false} -> {j,true/false}
auto [i,bi] = pi;
auto [j,bj] = pj;
assert(i >= 0 && i < n);
assert(j >= 0 && j < n);
p[2*i+bi].push_back(2*j+bj);
if(2*i+bi!=2*j+(!bj)) p[2*j+(!bj)].push_back(2*i+(!bi)); // 自动建立逻辑边
}
};
// ---------------- lib ----------------
int main(){
int n = read();
int m = read(); // xi \in [0,m]
int q = read();
TwoSat ts(n*(m+1));
auto _=[&](int i,int v){return i*(m+1)+v;}; // 编码 a[i] (>=v false, < v true)
auto ge=[&](int i,int v){return pair<int,bool>{_(i,v),false};}; // greater equal than
auto lt=[&](int i,int v){return pair<int,bool>{_(i,v),true};}; // less than
auto chk=[&](int v){return 0<=v && v<=m;};
rep(i,0,n) rep(v,1,m+1) ts.then(ge(i,v),ge(i,v-1)); // a[i]>=x 则 a[i] >= x-1 小于自动对称逻辑边
// 不能 < 0, 所以建立 < 0 则 >= 0
rep(i,0,n) ts.then(lt(i,0),ge(i,0));
while(q--){
int i=read()-1;
int j=read()-1;
int mn = read();
int mx = read();
// a[i]+a[j] >= x = mn, a[i] < v 则 a[j] >= x-v+1
rep(v,0,m+1) if(chk(mn-v+1)) ts.then(lt(i,v),ge(j,mn-v+1)); // j到i 自动对称
if(chk(mn-m)){ // mn-v+1 < 0的话 就是全部都可以 不需要建立失败逻辑, 而 a[j] >= x-v+1 > m 才需要
int v=mn-m;
ts.then(lt(i,v),ge(i,v));
ts.then(lt(j,v),ge(j,v));
}
// a[i]+a[j] <= x = mx, a[i] >= v 则 aj < x-v+1
rep(v,1,m+1) if(chk(mx-v+1)) ts.then(ge(i,v),lt(j,mx-v+1)); // j到i 自动对称
if(chk(mx+1)){ // 同理 建立失败逻辑
int v=mx+1;
ts.then(ge(i,v),lt(i,v));
ts.then(ge(j,v),lt(j,v));
}
}
vector<bool> res= {};
bool ok = ts.calc(res); // scc 联通分量 标识
if(!ok){
printf("-1\n");
return 0;
}
rep(i,0,n) per(v,0,m+1) if(!res[_(i,v)]){ // a[i] >= v
printf("%d ",v);// ans[i] = v;
break;
}
return 0;
}
Submission Info
Submission Time
2022-11-18 23:07:31+0900
Task
Ex - Constrained Sums
User
cromarmot
Language
C++ (GCC 9.2.1)
Score
600
Code Size
4291 Byte
Status
AC
Exec Time
3833 ms
Memory
570964 KiB
Compile Error
./Main.cpp: In function ‘int read()’:
./Main.cpp:5:23: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
5 | int read(){int r;scanf("%d",&r);return r;}
| ~~~~~^~~~~~~~~
Judge Result
Set Name
Sample
All
Score / Max Score
0 / 0
600 / 600
Status
Set Name
Test Cases
Sample
example0.txt, example1.txt
All
example0.txt, example1.txt, handmade0.txt, handmade1.txt, random0.txt, random1.txt, random10.txt, random11.txt, random12.txt, random13.txt, random14.txt, random15.txt, random16.txt, random17.txt, random18.txt, random19.txt, random2.txt, random20.txt, random21.txt, random22.txt, random23.txt, random24.txt, random25.txt, random26.txt, random27.txt, random28.txt, random29.txt, random3.txt, random30.txt, random31.txt, random32.txt, random33.txt, random34.txt, random35.txt, random4.txt, random5.txt, random6.txt, random7.txt, random8.txt, random9.txt
Case Name
Status
Exec Time
Memory
example0.txt
AC
5 ms
3676 KiB
example1.txt
AC
2 ms
3464 KiB
handmade0.txt
AC
2 ms
3796 KiB
handmade1.txt
AC
3 ms
3700 KiB
random0.txt
AC
2391 ms
447416 KiB
random1.txt
AC
2528 ms
479328 KiB
random10.txt
AC
1541 ms
442340 KiB
random11.txt
AC
1251 ms
275588 KiB
random12.txt
AC
3356 ms
533384 KiB
random13.txt
AC
3833 ms
570964 KiB
random14.txt
AC
328 ms
116776 KiB
random15.txt
AC
323 ms
120580 KiB
random16.txt
AC
1563 ms
450660 KiB
random17.txt
AC
895 ms
250072 KiB
random18.txt
AC
3669 ms
546588 KiB
random19.txt
AC
3818 ms
560884 KiB
random2.txt
AC
279 ms
111912 KiB
random20.txt
AC
317 ms
132816 KiB
random21.txt
AC
303 ms
121012 KiB
random22.txt
AC
1683 ms
469808 KiB
random23.txt
AC
1119 ms
286540 KiB
random24.txt
AC
3483 ms
539284 KiB
random25.txt
AC
3559 ms
553020 KiB
random26.txt
AC
229 ms
130840 KiB
random27.txt
AC
242 ms
138708 KiB
random28.txt
AC
1418 ms
405036 KiB
random29.txt
AC
1570 ms
464160 KiB
random3.txt
AC
264 ms
106236 KiB
random30.txt
AC
2581 ms
465224 KiB
random31.txt
AC
2667 ms
477612 KiB
random32.txt
AC
331 ms
112296 KiB
random33.txt
AC
334 ms
114284 KiB
random34.txt
AC
1481 ms
418732 KiB
random35.txt
AC
1306 ms
296508 KiB
random4.txt
AC
1400 ms
414552 KiB
random5.txt
AC
1204 ms
270380 KiB
random6.txt
AC
2647 ms
496424 KiB
random7.txt
AC
2775 ms
507964 KiB
random8.txt
AC
287 ms
116524 KiB
random9.txt
AC
303 ms
122852 KiB