\(d\)這麼小,你考慮直接對\(d\)個東西暴力
列舉\(x\)為\(a\)或\(b\)(\(c\)就不用了,因為\(a,b\)已經包含\(c\))了,剩下的就是個\(2-sat\)問題了
但是你發現有個情況是,在若\(a\)即\(b\)時,如果\(b\)被\(ban\)了,那麼\(a\)也要被\(ban\)
我們記錄一下被\(ban\)的點,然後在球方案的時候判一下(不得不用topo排序了..
但是其實也可以\(a\)連\(\lnot a\),就可以直接比較scc編號大小搞方案了
code:
#include #include #include #include #include using std::min;
const int size=1<<21;
char ibuf[size],*is,*it;
//#define gc() (is==it?(it=(is=ibuf)+fread(ibuf,1,size,stdin),is==it?eof:*is++):*is++)
#define gc() getchar()
template void read(t &x)
template void reads(t &x)
template void readb(t &x)
const int n=2e5+10;
int head[n],to[n],next[n],cnt;
void add(int u,int v)
struct _toki
toki[n];
int n,m,_n,yuu[n][4],ops[n],saki[n];
int val[n],ban[n],ban[n],q[n],bel[n],opsi[n];
int low[n],dfn[n],in[n],sta[n],tot,dfsclock;
std::vector e[n];
void tarjan(int now)
else if(in[v])
low[now]=min(low[now],dfn[v]);
} if(low[now]==dfn[now])
while(now!=k); }}
int solve()
add(yuu[a][b],yuu[c][d]);
add(ops[yuu[c][d]],ops[yuu[a][b]]);
} memset(in,0,sizeof in);
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
memset(bel,0,sizeof bel);
memset(opsi,0,sizeof opsi);
_n=dfsclock=0;
for(int i=1;i<=n<<1;i++)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=n;i++)
if(bel[i]==bel[i+n])
return -1;
memset(val,-1,sizeof val);
for(int i=1;i<=_n;i++) e[i].clear();
//int ecnt=0;
for(int u=1;u<=n<<1;u++)
int l=1,r=0;
for(int i=1;i<=_n;i++)
if(!in[i]&&!ban[i])
q[++r]=i;
while(l<=r)
else
}if(~solve()) return 0;
} puts("-1");
return 0;
}
2019.6.2 NOI2017 整數 解題報告
有一些比較簡單的 log 2n 做法 比如暴力在動態開點線段樹上維護每個位置為 0 還是 1 我們發現涉及到某一位加上 1 或者減去 1 實際上對其他位的影響只有區間覆蓋,通過線段樹上二分可以得到區間覆蓋的位置,然後暴力區間覆蓋即可。反正我這種菜雞大常數寫法只得到了68分.考慮利用勢能,注意到如果同...
NOI2017 遊戲(2 SAT 列舉)
2 sat板子題 如果沒有x這個字元的話,問題變成每個點都有兩種選法,有一些限制,顯然是個2 sat問題,設拆出來的兩個點分別為 i 和 i 則對於限制 x y 連邊 x,y y x 跑tarjan即可 2 sat基操嘛。即使現在有了x這個字元,我們也可以假裝乙個點仍只有兩種選法,列舉這兩種選法,並...
NOI2017 遊戲 2 sat演算法
題目 libreoj 題意 n場遊戲,有三種車abc,給定長度為n的字串,a 表示不能選a,b c 同理,x 表示不限,至多d個 x 有m個限制 i,hi,j,hj 表示如果第i場選擇車hi,那麼第j場必須選擇車hj。求可行方案,或無解。n 10 5,d 8。演算法 2 sat 題解 列舉 x 是 ...