Submission #36576932
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);
}
}
vector<vector<int> > sccgroup(){
rep(i,0,2*n) if(res[i]==-1) scc(i);
vector<pair<int,int> > gi;
rep(i,0,2*n) gi.push_back({res[i],i});
sort(gi.begin(),gi.end());
vector<vector<int> > group;
rep(i,0,2*n){
if(i==0||gi[i].first != gi[i-1].first) group.push_back({gi[i].second}); // new group
else group.back().push_back(gi[i].second); // same group
}
return group;
}
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){
auto group=sccgroup();
vector<int> i2g(2*n);
rep(i,0,group.size()) for(auto idx:group[i]) i2g[idx]=i;
rep(i,0,n) if(i2g[i*2]==i2g[i*2+1])return false; // 同一个块的真假都在一个scc里
vector<int> sccmutex(group.size()); // 互斥scc
rep(i,0,n) { // 每个点的true/false 状态互斥,唯一, 因为建立边时的对称逻辑边
sccmutex[i2g[i*2]] = i2g[i*2+1];
sccmutex[i2g[i*2+1]] = i2g[i*2];
}
vector<vector<int> > G(group.size()); // 图
vector<int> degree(group.size(),0);
// 跨scc的反向边, 做拓扑选择, (因为scc计算后,剩下的一定是偏序不会有环)
rep(i,0,2*n) for(auto j:p[i]) if(i2g[i]!=i2g[j]) G[i2g[j]].push_back(i2g[i]); // i -> j 反向边
for(auto &s:G){// 去重
sort(begin(s),end(s));
s.resize(unique(begin(s),end(s))-begin(s));
}
for(auto &s:G) for(auto t:s) degree[t]++;
vector<int> d0; // 入度为0
rep(v,0,degree.size()) if(!degree[v]) d0.push_back(v);
vector<int> sccpick(group.size(), -1); // scc -1未选, true选/false不选
rep(i,0,d0.size()) {
if(sccpick[d0[i]] == -1){ // 没有计算过
// prinpick("pick %d, unpick %d\n",d0[i],sccmutex[d0[i]]);
sccpick[d0[i]] = true;
sccpick[sccmutex[d0[i]]] = false;
}
for(auto item:G[d0[i]]) if(!(--degree[item])) d0.push_back(item); // 更新入度排序
}
ans = vector<bool>(n);
rep(i,0,n) ans[i] = sccpick[i2g[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:38:03+0900
Task
Ex - Constrained Sums
User
cromarmot
Language
C++ (GCC 9.2.1)
Score
600
Code Size
4941 Byte
Status
AC
Exec Time
1488 ms
Memory
397348 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
3748 KiB
example1.txt
AC
2 ms
3688 KiB
handmade0.txt
AC
2 ms
3784 KiB
handmade1.txt
AC
2 ms
3764 KiB
random0.txt
AC
1013 ms
302324 KiB
random1.txt
AC
1051 ms
330148 KiB
random10.txt
AC
913 ms
349824 KiB
random11.txt
AC
796 ms
194900 KiB
random12.txt
AC
1315 ms
378288 KiB
random13.txt
AC
1422 ms
397348 KiB
random14.txt
AC
492 ms
211188 KiB
random15.txt
AC
489 ms
215524 KiB
random16.txt
AC
924 ms
357168 KiB
random17.txt
AC
653 ms
183500 KiB
random18.txt
AC
1412 ms
381300 KiB
random19.txt
AC
1488 ms
388884 KiB
random2.txt
AC
484 ms
212224 KiB
random20.txt
AC
492 ms
229128 KiB
random21.txt
AC
470 ms
216160 KiB
random22.txt
AC
961 ms
373372 KiB
random23.txt
AC
703 ms
215260 KiB
random24.txt
AC
1183 ms
383676 KiB
random25.txt
AC
1152 ms
392356 KiB
random26.txt
AC
474 ms
238548 KiB
random27.txt
AC
500 ms
253264 KiB
random28.txt
AC
802 ms
318480 KiB
random29.txt
AC
1043 ms
371228 KiB
random3.txt
AC
462 ms
202140 KiB
random30.txt
AC
1052 ms
317344 KiB
random31.txt
AC
1073 ms
326912 KiB
random32.txt
AC
503 ms
206080 KiB
random33.txt
AC
506 ms
208332 KiB
random34.txt
AC
860 ms
329544 KiB
random35.txt
AC
816 ms
217152 KiB
random4.txt
AC
828 ms
326460 KiB
random5.txt
AC
734 ms
190780 KiB
random6.txt
AC
1115 ms
338792 KiB
random7.txt
AC
1157 ms
347116 KiB
random8.txt
AC
503 ms
221488 KiB
random9.txt
AC
517 ms
232680 KiB