#include using namespace std; using ll = long long; using ld = long double; /************************************************* * XOR Printer (yukicoder No.5022) * Multi-stage greedy with strict non-degradation: * 1. Compute best single-s solution (2^20 exhaustive), build its ops (baseline). * 2. Try repeating stages: * - On current board, find best s by 2^20 exhaustive. * - Build diff with XOR basis, generate C list. * - Choose W cells (those gaining with new s). * - If gain>0 AND total ops within T, commit; else stop. * 3. Compare final multi-stage score vs baseline. Output better. * * Moves only over necessary cells (C/W) with greedy routing to save ops. * Always safe: never outputs worse score than baseline. *************************************************/ // ===== XOR Basis (20-bit) with bitset representation ===== struct XorBasis { static const int B = 20; int v[B]; bitset<128> used[B]; XorBasis(){ memset(v,0,sizeof(v)); } void add(int x, const bitset<128>& bs){ bitset<128> c = bs; for(int b=B-1;b>=0;--b){ if(((x>>b)&1)==0) continue; if(v[b]==0){ v[b]=x; used[b]=c; return; } x ^= v[b]; c ^= used[b]; } } pair> build(int target) const{ int t=target, made=0; bitset<128> sel; sel.reset(); for(int b=B-1;b>=0;--b){ if(((t>>b)&1)==0) continue; if(v[b]==0) continue; t ^= v[b]; made ^= v[b]; sel ^= used[b]; } return {made, sel}; } }; inline ll eval_single(const vector& A, int s){ ll sum=0; for(int x:A){ int y=x^s; sum += (y>x?y:x); } return sum; } // Greedy visit order for a set of indices; append opch for each cell visited. static void visit_cells(int N, int &r, int &c, const vector& ids, vector& ops, char opch){ if(ids.empty()) return; vector used(ids.size(),0); for(size_t done=0; donetr){ ops.push_back('U'); --r; } while(ctc){ ops.push_back('L'); --c; } ops.push_back(opch); } } // Convert bitset<128> to vector (0..NN-1) static vector bs_to_vec(const bitset<128>& bs, int NN){ vector v; v.reserve(NN); for(int i=0;i>N>>T)) return 0; // N=10, T=1000 const int NN = N*N; vector> A2(N, vector(N)); for(int i=0;i>A2[i][j]; vector flatA(NN); for(int i=0;i bestScore_single){ bestScore_single=sc; bestS_single=s; } } // Build ops for baseline later (after we know if multi-stage beats it) auto build_baseline_ops = [&](int S)->vector{ XorBasis B; // basis on original board for(int i=0;i bs; bs.reset(); bs.set(i*N+j); B.add(A2[i][j], bs); } auto [S_real, cells] = B.build(S); if(S_real != S){ ll sc_real = eval_single(flatA, S_real); if(sc_real >= bestScore_single){ bestScore_single=sc_real; S=S_real; } else { auto tmp=B.build(S); cells = tmp.second; } } vector Cvec = bs_to_vec(cells, NN); vector Wvec; Wvec.reserve(NN); for(int id=0; ida) Wvec.push_back(id); } vector ops; ops.reserve(1200); int r=0,c=0; visit_cells(N,r,c,Cvec,ops,'C'); visit_cells(N,r,c,Wvec,ops,'W'); if((int)ops.size()>T) ops.resize(T); return ops; }; // ---------- Multi-stage attempt ---------- vector board = flatA; // current values int curS = 0; // current s vector ops_multi; // operations for multi-stage plan int r=0,c=0; // cursor pos ll currentScore = 0; for(int v:board) currentScore += v; auto time_start = chrono::steady_clock::now(); const double TIME_LIMIT = 1.90; // safety while(true){ if((int)ops_multi.size() > T-200) break; // margin double t = chrono::duration(chrono::steady_clock::now()-time_start).count(); if(t > TIME_LIMIT) break; // 1) best s on current board (exhaustive) int targetS=-1; ll bestGain=0; // gain over currentScore for(int s=0; s<(1<<20); ++s){ ll sum=0; for(int x:board){ int y=x^s; sum += (y>x?y:x); } ll g = sum - currentScore; if(g > bestGain){ bestGain=g; targetS=s; } } if(bestGain <= 0) break; // done // 2) Build basis on current board, realize diff int diff = curS ^ targetS; XorBasis B; for(int i=0;i bs; bs.reset(); bs.set(i*N+j); B.add(board[i*N+j], bs); } auto [diffReal, needCbs] = B.build(diff); int newS = curS ^ diffReal; // 3) choose W cells and compute new score with realizable newS vector Wvec; Wvec.reserve(NN); ll newScore = 0; for(int id=0; id a){ Wvec.push_back(id); newScore += b; } else newScore += a; } if(newScore <= currentScore) break; // cannot improve actually // Build ops for this stage to check T first vector tmp; tmp.reserve(needCbs.count()*6 + Wvec.size()*6 + 10); int tr=r, tc=c; vector Cvec = bs_to_vec(needCbs, NN); visit_cells(N, tr, tc, Cvec, tmp, 'C'); curS = newS; // after C, we hold newS visit_cells(N, tr, tc, Wvec, tmp, 'W'); // check if((int)ops_multi.size() + (int)tmp.size() > T) break; // commit ops_multi.insert(ops_multi.end(), tmp.begin(), tmp.end()); r=tr; c=tc; currentScore = newScore; for(int id: Wvec) board[id] ^= curS; } // Compare multi vs baseline if(currentScore > bestScore_single){ // multi-stage better if((int)ops_multi.size() > T) ops_multi.resize(T); for(char ch: ops_multi) cout<