Submission #34029401
Source Code Expand
#pragma GCC optimize("O3")
#pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
mt19937 gen32(time(0));
#define SZ 2666666
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define all(x) x.begin(),x.end()
typedef pair<int,int> pii;
typedef long long ll;
int n,k,S;
int id(int x,int y,int r=0) {
if(r) return y*S+x;
return x*S+y;
}
int gx(int t) {
return t/S;
}
int gy(int t) {
return t%S;
}
bool valid(int t) {
return t/S>=1&&t/S<=n&&t%S>=1&&t%S<=n;
}
int rpos() {
return (gen32()%n+1)*S+gen32()%n+1;
}
struct UFS {
int ff[SZ],cn[SZ][6],sz[SZ];
void clear() {
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j) {
int s=id(i,j); ff[s]=0; sz[s]=1;
memset(cn[s],0,sizeof cn[s]);
}
}
int find(int a) {
if(!ff[a]) return a;
return ff[a]=find(ff[a]);
}
bool link(int a,int b) {
int x=find(a),y=find(b);
if(x!=y) ff[x]=y,sz[y]+=sz[x];
return x!=y;
}
int gsz(int x) {
return sz[find(x)];
}
}U;
int we[2333];
int B=SZ/3,ea[SZ],eb[SZ],ek[SZ],ms[SZ],vv[SZ];
struct arr {
int w[101*101];
vector<pii> mvs;
void add_move(int s,int d) {
assert(valid(s)&&valid(s+d)&&w[s]<0&&w[s+d]==0);
mvs.push_back(make_pair(s,d));
w[s+d]=w[s]; w[s]=0;
}
void initufs() const {
U.clear();
for(int i=1;i<=n;++i)
for(int j=1,b;j<=n;++j) if((b=w[id(i,j)])>0) U.link(ea[b],eb[b]);
}
//(val, num_cc)
pair<pii,int> stats() const {
initufs();
for(int i=1;i<=n;++i)
for(int j=1,b;j<=n;++j) if((b=w[id(i,j)])<0) ++U.cn[U.find(id(i,j))][-b];
int ans=0,num_cc=0,ans2=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j) {
int o=id(i,j),ct=0;
if(U.ff[o]||w[o]>=0) continue;
int*cn=U.cn[o]; ++num_cc;
for(int s=1;s<=k;++s) {
ans-=ct*cn[s]; ct+=cn[s];
ans+=cn[s]*(cn[s]-1)/2;
ans2+=we[s]*cn[s]*(cn[s]-1)/2;
}
}
return make_pair(make_pair(ans,ans2),num_cc);
}
bool validate(int lb=-1e9) const {
auto st=stats();
return (int)mvs.size()<=st.se&&st.fi.se>lb;
}
int gap() const {
return stats().se-(int)mvs.size();
}
pii val() const {
return stats().fi;
}
void add_bridge(int x,int y,int d) {
++B; ea[B]=x; eb[B]=y; ek[B]=d;
for(int p=x;p!=y;p+=d)
if(w[p]==0) w[p]=B;
else if(p!=x) {
cerr<<x<<"~"<<y<<" "<<d<<" but at "<<p<<":"<<w[p]<<" "<<gx(x)<<","<<gy(x)<<" "<<gx(y)<<","<<gy(y)<<"\n";
dbg();
assert(p==x);
}
}
void reset_bridge(int bid) {
for(int p=ea[bid];p!=eb[bid];p+=ek[bid]) {
if(w[p]>0) {
assert(w[p]==bid);
w[p]=0;
}
}
}
bool bridge_ready(int x,int y,int g) {
for(int p=x;p!=y;p+=g) if(w[p]>0) return false;
return true;
}
void smart_greedy(int rep_max=1) {
mt19937 mygen(23333);
static int best_val;
static arr best_rst;
if(rep_max>1) {
best_val=val().se;
best_rst=*this;
}
for(int rep=0;rep<rep_max;++rep) {
initufs();
vector<array<int,3>> v;
static int st[SZ];
for(int dir=0;dir<2;++dir)
for(int i=1;i<=n;++i) {
int sn=0;
for(int j=1;j<=n;++j) if(w[id(i,j,dir)]) st[++sn]=j;
for(int j=1;j<sn;++j) {
int l=st[j],r=st[j+1];
if(w[id(i,l,dir)]<0&&w[id(i,l,dir)]==w[id(i,r,dir)]) {
// if(!validc(-w[id(i,l,dir)])) continue;
int x=id(i,l,dir),y=id(i,r,dir),p=dir?S:1;
v.push_back(array<int,3>{x,y,p});
}
}
}
static vector<int> yg[SZ];
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j) yg[id(i,j)].clear();
static int vvs[SZ],CC=0;
++CC;
priority_queue<pii> pq;
auto cons=[&](int i) {
pq.push(pii(U.gsz(v[i][0])*U.gsz(v[i][1]),i));
};
for(int i=0;i<(int)v.size();++i) {
yg[U.find(v[i][0])].push_back(i);
yg[U.find(v[i][1])].push_back(i);
cons(i);
}
// set<int> vvs;
while(!pq.empty()) {
int i=pq.top().se; pq.pop();
if(vvs[i]==CC) continue;
vvs[i]=CC;
int gx=U.find(v[i][0]),gy=U.find(v[i][1]);
if(gx==gy||!bridge_ready(v[i][0],v[i][1],v[i][2]))
continue;
add_bridge(v[i][0],v[i][1],v[i][2]);
if(yg[gx].size()>yg[gy].size()) swap(gx,gy);
U.ff[gx]=gy; U.sz[gy]+=U.sz[gx];
auto&ygy=yg[gy];
for(auto t:yg[gx]) if(vvs[t]-CC) ygy.push_back(t);
for(auto a:ygy) if(vvs[a]-CC) cons(a);
}
if(rep_max>1) {
auto cvv=val().se;
if(cvv>best_val) {
best_val=cvv;
best_rst=*this;
}
}
if(rep+1<rep_max) {
set<int> bri;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j) if(w[id(i,j)]>0) bri.insert(w[id(i,j)]);
for(auto t:bri) if(mygen()%3==0) reset_bridge(t);
}
}
if(rep_max>1)
*this=best_rst;
auto g=gap();
if(g>=0) return;
while(g<0) {
initufs();
static pii bris[SZ]; int bn=0;
for(int i=1;i<=n;++i)
for(int j=1,b;j<=n;++j) if((b=w[id(i,j)])>0) bris[++bn]=pii(-U.gsz(ea[b]),b);
sort(bris+1,bris+1+bn);
bn=unique(bris+1,bris+1+bn)-(bris+1);
for(int cnt=0;cnt<10&&g<0;++cnt) {
++g; auto t=bris[bn--];
reset_bridge(t.se);
}
}
}
void dbg() const {
printf("total %d lines [ST]\n",n);
for(int i=1;i<=n;++i) {
for(int j=1;j<=n;++j) {
int s=id(i,j);
if(w[s]<=0) printf("%d",-w[s]);
else printf("%c"," abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"[w[s]%52+1]);
}
printf("\n");
}
printf("total %d lines [ED]\n",n);
}
void clean_junk() {
set<int> bs;
for(int i=1;i<=n;++i)
for(int j=1,b;j<=n;++j) if((b=w[id(i,j)])>0) bs.insert(b);
vector<int> bs_sf(all(bs));
shuffle(all(bs_sf),gen32);
U.clear();
for(auto b:bs_sf)
if(!U.link(ea[b],eb[b])) {
reset_bridge(b);
continue;
}
}
string output() const {
set<pii> cons;
for(int i=1;i<=n;++i)
for(int j=1,b;j<=n;++j)
if((b=w[id(i,j)])>0) cons.insert(mp(ea[b],eb[b]));
stringstream t;
t<<mvs.size()<<"\n";
for(auto m:mvs) {
int x1=gx(m.fi),y1=gy(m.fi),x2=gx(m.fi+m.se),y2=gy(m.fi+m.se);
assert(x1%2==1&&y1%2==1&&x2%2==1&&y2%2==1);
t<<x1/2<<" "<<y1/2<<" "<<x2/2<<" "<<y2/2<<"\n";
}
// t<<gx(m.fi)-1<<" "<<gy(m.fi)-1<<" "<<gx(m.fi+m.se)-1<<" "<<gy(m.fi+m.se)-1<<"\n";
// printf("0\n"); // no moves so far
vector<pii> op;
U.clear();
for(auto c:cons) {
if(!U.link(c.fi,c.se)) continue;
op.pb(c);
}
t<<op.size()<<"\n";
// printf("%d\n",(int)op.size());
for(auto c:op) {
int x1=gx(c.fi),y1=gy(c.fi),x2=gx(c.se),y2=gy(c.se);
assert(x1%2&&y1%2&&x2%2&&y2%2);
t<<x1/2<<" "<<y1/2<<" "<<x2/2<<" "<<y2/2<<"\n";
// printf("%d %d %d %d\n",x1,y1,x2,y2);
}
return t.str();
}
bool sample_erase() {
if(mvs.empty()) return 0;
int r=gen32()%mvs.size();
int so=mvs[r].fi,tg=so+mvs[r].se;
for(int j=r+1;j<(int)mvs.size();++j)
if(mvs[j].fi==tg||mvs[j].se+mvs[j].fi==tg
||mvs[j].fi==so||mvs[j].se+mvs[j].fi==so) return 0;
assert(w[tg]<0);
mvs.erase(mvs.begin()+r);
if(w[so]>0) reset_bridge(w[so]);
for(int d:{1,-1,S,-S}) {
int b;
if(valid(tg+d)&&(b=w[tg+d])>0&&(ea[b]==tg||eb[b]==tg)) reset_bridge(b);
}
assert(so!=tg);
assert(valid(so)&&valid(tg));
w[so]=w[tg]; w[tg]=0;
// validate();
return 1;
}
void clear_bridges() {
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j) {
auto&s=w[id(i,j)];
if(s>0) s=0;
}
}
}best,cur;
inline pair<pii,arr> add_freebie(arr t) {
t.smart_greedy(5);
return make_pair(t.val(),t);
}
pii add_freebie_val(arr t) {
return add_freebie(t).fi;
}
void reassign_bridge_id() {
// new edges at [1/3,2/3]
// move everything to [2/3,1], and then move back to [0,1/3]
static int C=0;
for(int st=SZ/3*2;st>=0;st-=max(st,1)) {
++C; int A=st;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) {
int t=id(i,j); auto &v=best.w[t];
if(v>0) {
if(vv[v]!=C) {
vv[v]=C; ms[v]=++A;
ea[A]=ea[v]; eb[A]=eb[v]; ek[A]=ek[v];
}
v=ms[v];
}
}
}
B=SZ/2;
}
void input() {
cin>>n>>k; S=n*2+1;
assert(k<=5);
for(int i=1;i<=n;++i) {
string l; cin>>l;
for(int j=1;j<=n;++j) {
int c=l[j-1]-'0';
assert(0<=c&&c<=k);
best.w[id(i*2-1,j*2-1)]=-c;
}
}
n=n*2-1;
cur=best;
}
#ifndef ONLINE_JUDGE
//#define ENDLESS_TEST
#endif
int eval(int c) {
vector<pii> vp;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(cur.w[id(i,j)]==-c) vp.pb(pii(i,j));
int ans=0;
for(auto t:vp) {
int mi=2e9;
for(auto s:vp) if(t!=s) {
auto a=t,b=s;
for(int d=0;d<2;++d) {
if(a.fi>b.fi) swap(a,b);
int ca=abs(a.fi-b.fi);
for(int g=a.fi;g<=b.fi&&ca<mi;++g) {
for(int u=min(a.se,b.se);u<=max(a.se,b.se);++u) {
int o=cur.w[id(g,u,d)];
ca+=o&&o!=-c;
}
if(ca>=mi) break;
for(int u=a.fi;u<=g;++u) {
int o=cur.w[id(u,a.se,d)];
ca+=o&&o!=-c;
}
if(ca>=mi) break;
for(int u=g;u<=b.fi;++u) {
int o=cur.w[id(b.se,u,d)];
ca+=o&&o!=-c;
}
}
mi=min(mi,ca);
swap(a.fi,a.se);
swap(b.fi,b.se);
}
}
ans+=mi;
}
return ans;
}
int main() {
input();
vector<pii> ve;
for(int i=1;i<=k;++i) ve.pb(mp(eval(i),i));
sort(ve.begin(),ve.end());
for(int i=1;i<=k;++i) we[i]=1;
for(int i=0;i<2&&i<ve.size();++i) we[ve[i].se]=(3-i)*3;
const int dir[]={2,-2,2*S,-2*S};
int nxt_rb=0,og=-1;
int best_val=-1;
int last_gap=2e9;
int last_se=-1;
arr best_arr; // debug only!!!
string best_op;
int ty=0;
add_freebie(cur).se.initufs();
while(1) {
#ifndef ENDLESS_TEST
if(clock()>=CLOCKS_PER_SEC*2.8) break;
#endif
if(--nxt_rb>=0) {
while(gen32()%5)
if(gen32()%(7-max(5-last_gap/10,0))==0)
cur.sample_erase();
int csb=0,bestv=-1;
vector<int> info;
for(int att=1;att<=300&&csb<20;++att) {
/**/
int x=0; while(cur.w[x]>=0) x=rpos();
int mv=0;
// cerr<<"B";
if(gen32()%3) {
int t=gen32()%4; mv=dir[t];
bool good=valid(x+mv)&&cur.w[x+mv]==0;
if(!good) continue;
}
int d=mv;
while(d==mv||d==-mv) d=dir[gen32()%4];
// cerr<<"C";
int y=x+mv+d;
while(valid(y)&&cur.w[y]>=0) y+=d;
if(!valid(y)) continue;
int sk1=-1,md=0;
if(cur.w[x]!=cur.w[y]) {
// if(mv) continue;
for(auto dd:dir) if(valid(y+dd)) {
if(dd!=d&&dd!=-d&&cur.w[y+dd]==0) {
if(!md||gen32()%2) md=dd;
}
}
if(!md) continue;
sk1=y; y+=d;
while(valid(y)&&cur.w[y]>=0) y+=d;
if(!valid(y)) continue;
if(cur.w[x]!=cur.w[y]) continue;
}
if(U.find(x)==U.find(y)) continue;
if(!mv&&sk1==-1) continue;
auto ps=U.gsz(x)*U.gsz(y);
//x^2/2 -> (x/2)^2/2
if(sk1!=-1&&U.gsz(sk1)*U.gsz(sk1)/2>ps&&ty) continue;
if(ps>bestv)
bestv=ps, info={ps,sk1,md,x,mv}, ++csb;
/*
if(sk1!=-1)
cur.add_move(sk1,md);
if(mv)
cur.add_move(x,mv);
cerr<<"!"<<U.gsz(x)*U.gsz(y)<<"\n";
break;*/
}
if(!csb) continue;
auto sk1=info[1],md=info[2],x=info[3],mv=info[4];
if(sk1!=-1)
cur.add_move(sk1,md);
if(mv)
cur.add_move(x,mv);
}
else {
bool upd=0;
auto afb=add_freebie(cur);
if(afb.fi.se>=last_se) {
best=cur;
last_se=afb.fi.se; upd=1;
}
reassign_bridge_id(); cur=best;
nxt_rb=gen32()%3+1;
while(gen32()%3) ++nxt_rb;
ty=gen32()%3;
if(upd) {
auto added=afb;
if(added.fi.fi>best_val) {
best_val=added.fi.fi;
best_arr=added.se;
best_op=best_arr.output();
last_gap=best_arr.gap();
#ifdef ENDLESS_TEST
{
/*
best_arr.clear_bridges();
cout<<best_arr.output()<<"\n";
best_arr.smart_greedy();
if(best_arr.validate())
cout<<best_arr.output()<<"\n";*/
cout<<best_op<<"\n";
}
#endif
cerr<<best_val<<"|"<<added.fi.se<<"+ "<<clock()*1./CLOCKS_PER_SEC<<" G"<<last_gap<<" S"<<og<<"\n";
best_arr.clear_bridges();
// cerr<<" [RESET]"<<best_arr.val()<<"|"<<add_freebie_val(best_arr)<<"A\n";
best_arr.smart_greedy(50);
auto cv=best_arr.val().fi;
if(cv>best_val) {
best_val=cv; best_op=best_arr.output();
cerr<<"actual:"<<cv<<"\n";
}
// cerr<<" [RESET]"<<best_arr.val()<<"|"<<add_freebie_val(best_arr)<<"B\n";
// cerr<<"val="<<best_arr.val()<<"\n";
// assert(best_arr.val()==best_val);
// best_arr.dbg();
}
}
else
afb.se.initufs();
og=nxt_rb;
}
// system("pause");
}
puts(best_op.c_str());
cerr<<"val="<<best_val<<"\n";
}
Submission Info
| Submission Time |
|
| Task |
A - Server Room |
| User |
fjzzq2002 |
| Language |
C++ (GCC 9.2.1) |
| Score |
230214 |
| Code Size |
15640 Byte |
| Status |
AC |
| Exec Time |
2824 ms |
| Memory |
67312 KiB |
Compile Error
./Main.cpp: In function ‘int main()’:
./Main.cpp:377:23: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::pair<int, int> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
377 | for(int i=0;i<2&&i<ve.size();++i) we[ve[i].se]=(3-i)*3;
| ~^~~~~~~~~~
Judge Result
| Set Name |
test_all |
| Score / Max Score |
230214 / 1237500 |
| Status |
|
| Set Name |
Test Cases |
| test_all |
subtask_01_01.txt, subtask_01_02.txt, subtask_01_03.txt, subtask_01_04.txt, subtask_01_05.txt, subtask_01_06.txt, subtask_01_07.txt, subtask_01_08.txt, subtask_01_09.txt, subtask_01_10.txt, subtask_01_11.txt, subtask_01_12.txt, subtask_01_13.txt, subtask_01_14.txt, subtask_01_15.txt, subtask_01_16.txt, subtask_01_17.txt, subtask_01_18.txt, subtask_01_19.txt, subtask_01_20.txt, subtask_01_21.txt, subtask_01_22.txt, subtask_01_23.txt, subtask_01_24.txt, subtask_01_25.txt, subtask_01_26.txt, subtask_01_27.txt, subtask_01_28.txt, subtask_01_29.txt, subtask_01_30.txt, subtask_01_31.txt, subtask_01_32.txt, subtask_01_33.txt, subtask_01_34.txt, subtask_01_35.txt, subtask_01_36.txt, subtask_01_37.txt, subtask_01_38.txt, subtask_01_39.txt, subtask_01_40.txt, subtask_01_41.txt, subtask_01_42.txt, subtask_01_43.txt, subtask_01_44.txt, subtask_01_45.txt, subtask_01_46.txt, subtask_01_47.txt, subtask_01_48.txt, subtask_01_49.txt, subtask_01_50.txt |
| Case Name |
Status |
Exec Time |
Memory |
| subtask_01_01.txt |
AC |
2819 ms |
67240 KiB |
| subtask_01_02.txt |
AC |
2818 ms |
66968 KiB |
| subtask_01_03.txt |
AC |
2817 ms |
66952 KiB |
| subtask_01_04.txt |
AC |
2824 ms |
67244 KiB |
| subtask_01_05.txt |
AC |
2813 ms |
66988 KiB |
| subtask_01_06.txt |
AC |
2815 ms |
67152 KiB |
| subtask_01_07.txt |
AC |
2813 ms |
66860 KiB |
| subtask_01_08.txt |
AC |
2814 ms |
67312 KiB |
| subtask_01_09.txt |
AC |
2815 ms |
67112 KiB |
| subtask_01_10.txt |
AC |
2818 ms |
67112 KiB |
| subtask_01_11.txt |
AC |
2814 ms |
66996 KiB |
| subtask_01_12.txt |
AC |
2818 ms |
67212 KiB |
| subtask_01_13.txt |
AC |
2819 ms |
67224 KiB |
| subtask_01_14.txt |
AC |
2818 ms |
66916 KiB |
| subtask_01_15.txt |
AC |
2817 ms |
67012 KiB |
| subtask_01_16.txt |
AC |
2822 ms |
67168 KiB |
| subtask_01_17.txt |
AC |
2815 ms |
67196 KiB |
| subtask_01_18.txt |
AC |
2818 ms |
67156 KiB |
| subtask_01_19.txt |
AC |
2817 ms |
67028 KiB |
| subtask_01_20.txt |
AC |
2814 ms |
67008 KiB |
| subtask_01_21.txt |
AC |
2817 ms |
66976 KiB |
| subtask_01_22.txt |
AC |
2813 ms |
66948 KiB |
| subtask_01_23.txt |
AC |
2822 ms |
67116 KiB |
| subtask_01_24.txt |
AC |
2818 ms |
67084 KiB |
| subtask_01_25.txt |
AC |
2815 ms |
66996 KiB |
| subtask_01_26.txt |
AC |
2818 ms |
67128 KiB |
| subtask_01_27.txt |
AC |
2819 ms |
67312 KiB |
| subtask_01_28.txt |
AC |
2814 ms |
66924 KiB |
| subtask_01_29.txt |
AC |
2814 ms |
66996 KiB |
| subtask_01_30.txt |
AC |
2818 ms |
67108 KiB |
| subtask_01_31.txt |
AC |
2814 ms |
67188 KiB |
| subtask_01_32.txt |
AC |
2815 ms |
67200 KiB |
| subtask_01_33.txt |
AC |
2813 ms |
67080 KiB |
| subtask_01_34.txt |
AC |
2818 ms |
66968 KiB |
| subtask_01_35.txt |
AC |
2818 ms |
67096 KiB |
| subtask_01_36.txt |
AC |
2818 ms |
67160 KiB |
| subtask_01_37.txt |
AC |
2814 ms |
67032 KiB |
| subtask_01_38.txt |
AC |
2819 ms |
67192 KiB |
| subtask_01_39.txt |
AC |
2818 ms |
67244 KiB |
| subtask_01_40.txt |
AC |
2818 ms |
66984 KiB |
| subtask_01_41.txt |
AC |
2813 ms |
66824 KiB |
| subtask_01_42.txt |
AC |
2814 ms |
67036 KiB |
| subtask_01_43.txt |
AC |
2818 ms |
67048 KiB |
| subtask_01_44.txt |
AC |
2818 ms |
67144 KiB |
| subtask_01_45.txt |
AC |
2813 ms |
66932 KiB |
| subtask_01_46.txt |
AC |
2817 ms |
66888 KiB |
| subtask_01_47.txt |
AC |
2814 ms |
67068 KiB |
| subtask_01_48.txt |
AC |
2822 ms |
67260 KiB |
| subtask_01_49.txt |
AC |
2819 ms |
67076 KiB |
| subtask_01_50.txt |
AC |
2814 ms |
67008 KiB |