結果
| 問題 |
No.5005 3-SAT
|
| ユーザー |
|
| 提出日時 | 2022-07-07 19:40:15 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,983 ms / 2,000 ms |
| コード長 | 4,431 bytes |
| コンパイル時間 | 4,247 ms |
| 実行使用メモリ | 6,952 KB |
| スコア | 108,329 |
| 最終ジャッジ日時 | 2022-07-07 19:43:48 |
| 合計ジャッジ時間 | 208,315 ms |
|
ジャッジサーバーID (参考情報) |
judge11 / judge15 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 100 |
ソースコード
#include "bits/stdc++.h"
using namespace std;
// #define LOCAL
using usize=unsigned long long;
using i64=long long;
using f64=double;
template<typename T> using Vec=vector<T>;
__attribute__((constructor)) void constructor(){cin.tie(nullptr);cin.sync_with_stdio(false);}
namespace rnd{
static usize S=88172645463325252;
inline usize next(){
S^=S<<7;
S^=S>>9;
return S;
}
}
inline f64 get_time(){
static f64 START=-1.;
timespec ts;
timespec_get(&ts,TIME_UTC);
f64 t=f64(ts.tv_sec)+f64(ts.tv_nsec)*1e-9;
if(START<0){START=t;}
return t-START;
}
#ifdef LOCAL
#define debug(...) debug_sub(0,#__VA_ARGS__,__VA_ARGS__)
template<typename N,typename T>
void debug_sub(int i,const N& name,const T& a){
for(;name[i]!=',' && name[i]!='\0';++i) cerr<<name[i];
cerr<<": "<<a<<endl;
}
template<typename N,typename T1,typename... T2>
void debug_sub(int i,const N& name,const T1& a,const T2& ...b){
for(;name[i]!=',' && name[i]!='\0';++i) cerr<<name[i];
cerr<<": "<<a<<", ";
debug_sub(i+1,name,b...);
}
#else
#define debug(...)
#endif
constexpr usize N=256;
constexpr usize M=2048;
struct In{
array<array<Vec<usize>,2>,N> edge{};
inline In(){
usize id[3];
usize f[3];
for(usize i=0;i<M;++i){
cin>>id[0]>>id[1]>>id[2]>>f[0]>>f[1]>>f[2];
for(usize j=0;j<3;++j){
edge[id[j]][f[j]].emplace_back(i);
}
}
}
};
struct Out{
array<bool,N> out{};
array<usize,M> cnt{};
array<array<Vec<usize>,2>,N> edge{};
inline Out(){
usize r=!0;
for(usize i=0;i<N;++i){
if((i&63)==0){
r=rnd::next();
}
out[i]=(r&1)==0;
r>>=1;
}
}
inline void re(In& input,usize r){
cnt.fill(0);
for(usize i=0;i<N;++i){
for(usize j=0;j<2;++j){
edge[i][j].clear();
for(const auto k:input.edge[i][j]){
if(k<r){
edge[i][j].emplace_back(k);
}
}
}
for(const auto j:edge[i][out[i]]){
++cnt[j];
}
}
}
inline i64 score(){
i64 ret=0;
for(const auto i:cnt){
ret+=(i!=0);
}
return ret;
}
inline bool change(i64 add,usize idx,i64& score){
i64 diff=0;
bool f=out[idx];
for(const auto i:edge[idx][f]){
--cnt[i];
diff-=cnt[i]==0;
}
for(const auto i:edge[idx][!f]){
++cnt[i];
diff+=cnt[i]==1;
}
if(add<=diff){
score+=diff;
out[idx]=!f;
return true;
}
for(const auto i:edge[idx][f]) ++cnt[i];
for(const auto i:edge[idx][!f]) --cnt[i];
return false;
}
};
constexpr f64 TL=1.98;
bool sa(usize r,Out& cur,usize lim){
i64 score=cur.score();
usize iter=0;
usize up=0;
array<i64,256> th;
for(;;){
if((iter&2047)==0){
if(get_time()>=TL) break;
f64 p=f64(iter)/f64(lim);
if(p>=1.) break;
constexpr f64 T=0.3;
f64 heat=T*(1.-p);
usize id=0;
do{
usize r=rnd::next();
th[id]=heat*log(f64(r&4294967295)/4294967296.);
th[id+1]=heat*log(f64(r>>32)/4294967296.);
id+=2;
}while(id<th.size());
}
++iter;
if(cur.change(th[iter&255],rnd::next()%N,score)){
if(score==r) break;
++up;
}
}
f64 p=f64(up)/f64(iter);
debug(r,iter,p);
debug(score);
assert(score==cur.score());
return score==r;
}
array<bool,256> solve(In& input){
Out out;
array<bool,256> ans=out.out;
usize best=0;
usize pos=1000;
usize iter=0;
while(get_time()<=TL){
++iter;
out.re(input,pos);
if(sa(pos,out,2000000)){
ans=out.out;
best=pos;
pos+=4;
}
else{
out.out=ans;
pos=best+1;
}
}
debug(iter);
debug(best);
return ans;
}
int main(){
In input;
array<bool,256> ans=solve(input);
for(i64 i=ans.size()-1;0<=i;--i){
cout<<ans[i];
}
cout<<endl;
}