#include using namespace std; using ll = long long; /**************************************************** * XOR Printer – Block Split Non-degrading Version * - Start with best single-s (2^20 exhaustive) to get a strong base. * - Then repeat over 5x5 quadrants (4 blocks): for each block, search * the best s (2^20) that improves ONLY that block (rest unchanged). * Apply it (C diff + W in that block) iff global score strictly increases. * - Greedy routing only over required cells (C/W) to save ops so we can * process multiple blocks within T=1000. * - Every adoption is guarded by score comparison ⇒ non-degrading. ****************************************************/ // ===== XOR Basis (20-bit) ===== struct XorBasis { static const int B = 20; int v[B]; vector mask[B]; XorBasis(){ memset(v,0,sizeof(v)); } void add(int x, const vector& cells){ vector c = cells; for(int b=B-1; b>=0; --b){ if(((x>>b)&1)==0) continue; if(!v[b]){ v[b]=x; mask[b]=c; return; } x ^= v[b]; vector a = mask[b], res; res.reserve(c.size()+a.size()); sort(c.begin(),c.end()); sort(a.begin(),a.end()); size_t i=0,j=0; while(i> build(int target) const{ int t=target, made=0; vector sel; for(int b=B-1; b>=0; --b){ if(((t>>b)&1)==0) continue; if(!v[b]) continue; t ^= v[b]; made ^= v[b]; vector a = mask[b], res; res.reserve(sel.size()+a.size()); sort(sel.begin(),sel.end()); sort(a.begin(),a.end()); size_t i=0,j=0; while(i& A, int s){ ll sum=0; for(int x:A){ int y=x^s; sum += (y>x?y:x);} return sum; } static void greedy_visit(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; donerr){ ops.push_back('U'); --r; } while(ccc){ ops.push_back('L'); --c; } ops.push_back(opch); } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N,T; if(!(cin>>N>>T)) return 0; // N=10, T=1000 const int NN=N*N, BITS=20; vector> A(N, vector(N)); for(int i=0;i>A[i][j]; // flatten board vector board(NN); for(int i=0;i ops; ops.reserve(3000); int r=0,c=0; // cursor int curS = 0; // current s held auto start = chrono::steady_clock::now(); const double TIME_LIMIT = 1.90; // seconds safety // ====== STEP 1: global best single s ====== ll baseSum = 0; for(int v:board) baseSum+=v; int bestS = 0; ll bestGain = 0; for(int s=0; s<(1<x?y:x);} ll g=tot-baseSum; if(g>bestGain){bestGain=g; bestS=s;} } if(bestGain>0){ // Build basis from board XorBasis B; for(int i=0;i{idx}); } int diff = curS ^ bestS; auto [diffReal, needC] = B.build(diff); int newS = curS ^ diffReal; // recompute with realizable s vector wCells; wCells.reserve(NN); ll afterSum=0; for(int id=0; ida){ wCells.push_back(id); afterSum+=b; } else afterSum+=a; } if(afterSum>baseSum){ // emit greedy_visit(N,r,c,needC,ops,'C'); curS=newS; greedy_visit(N,r,c,wCells,ops,'W'); for(int id:wCells) board[id]^=curS; } } // ====== STEP 2: block loop ====== // Quadrants: 5x5 each vector> ranges = {{0,5},{5,10}}; // [l,r) auto elapsed = [&](){return chrono::duration(chrono::steady_clock::now()-start).count();}; bool improved=true; while(improved){ improved=false; if((int)ops.size()>T-200) break; if(elapsed()>TIME_LIMIT) break; // try each block for(auto [ri,re]:ranges){ for(auto [ci,ce]:ranges){ // collect ids of this block vector ids; ids.reserve(25); for(int i=ri;ia?b:a);} ll g=tot-blkSum; if(g>gain){gain=g; ts=s;} } if(gain<=0) continue; // block cannot improve by itself // realize diff with current board int diff = curS ^ ts; XorBasis B; for(int i=0;i{idx}); } auto [diffReal, needC] = B.build(diff); int newS = curS ^ diffReal; // re-eval gain on block with realizable newS vector wCells; wCells.reserve(ids.size()); ll newBlkSum=0; for(int id:ids){ int a=board[id]; int b=a^newS; if(b>a){ wCells.push_back(id); newBlkSum+=b;} else newBlkSum+=a; } ll realGain = newBlkSum - blkSum; if(realGain<=0) continue; // skip // also check total ops budget vector tmp; tmp.reserve(needC.size()*6 + wCells.size()*6 + 10); int tr=r, tc=c; greedy_visit(N,tr,tc,needC,tmp,'C'); greedy_visit(N,tr,tc,wCells,tmp,'W'); if((int)ops.size()+ (int)tmp.size() > T) continue; // can't afford // commit ops.insert(ops.end(), tmp.begin(), tmp.end()); r=tr; c=tc; curS=newS; for(int id:wCells) board[id]^=curS; improved=true; if((int)ops.size()>T-200) break; if(elapsed()>TIME_LIMIT) break; } if(improved && (int)ops.size()>T-200) break; if(elapsed()>TIME_LIMIT) break; } } if((int)ops.size()>T) ops.resize(T); for(char ch: ops) cout<