結果

問題 No.5002 stick xor
ユーザー polylogKpolylogK
提出日時 2018-05-26 00:01:02
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
TLE  
実行時間 -
コード長 2,595 bytes
コンパイル時間 7,687 ms
実行使用メモリ 3,408 KB
スコア 0
最終ジャッジ日時 2018-05-26 00:01:13
ジャッジサーバーID
(参考情報)
judge10 /
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 TLE -
testcase_01 -- -
testcase_02 -- -
testcase_03 -- -
testcase_04 -- -
testcase_05 -- -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
testcase_25 -- -
testcase_26 -- -
testcase_27 -- -
testcase_28 -- -
testcase_29 -- -
testcase_30 -- -
testcase_31 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using std::cout;
using std::endl;
using std::cin;

struct SegmentTree{
	std::vector<int> seg;
	int sz = 1;
	
	SegmentTree(int n){
		while(sz < n) sz *= 2;
		seg.assign(sz * 2, 0);
	}
	
	void update(int k, int x){
		k += sz - 1;
		seg[k] = x;
		
		while(k){
			k = (k - 1) / 2;
			seg[k] = seg[2 * k + 1];
		}
	}
	
	int get(int a, int b){
		return get(a, b, 0, 0, sz);
	}
	
	int get(int a, int b, int k, int l, int r){
		if(b<=l||r<=a) return 0;
		if(a<=l&&r<=b) return seg[k];
		
		return get(a, b, 2 * k + 1, l, (l + r) / 2) + get(a, b, 2 * k + 2, (l + r) / 2, r);
	}
	
	void reverse(int a, int b){
		for(int i = a; i < b; i++) update(i, 1 - get(i, i + 1));
	}
};

struct Node{
	int score;
	std::vector<SegmentTree> seg;
	std::vector<std::tuple<int, int, int, int>> vec;
	
	Node() {}
	Node(int score, std::vector<SegmentTree> seg, std::vector<std::tuple<int, int, int, int>> vec) : score(score), seg(seg), vec(vec) {};
	bool operator<(const Node b) const{return score > b.score;}
};

std::vector<int> l;
int n, k, K = 10, count = 0;

int main(){
	cin >> n >> k; std::vector<std::string> s(n); l.resize(k);
	for(int i = 0; i < k; i++) cin >> l[i];
	for(int i = 0; i < n; i++) cin >> s[i];
	
	std::vector<SegmentTree> seg(n, SegmentTree(n));
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < n; j++) {
			if(s[i][j] == '0') {
				seg[i].update(j, 1);
				count++;
			}
		}
	}
	
	std::priority_queue<Node> qu[2];
	qu[0].push({0, seg, std::vector<std::tuple<int, int, int, int>>()});
	
	for(int i = 0; i < k; i++){
		while(!qu[i % 2].empty()){
			Node p = qu[i % 2].top(); qu[i % 2].pop();
			
			for(int x = 0; x < 20; x++){
				std::vector<SegmentTree> seg = p.seg;
				std::vector<std::tuple<int, int, int, int>> vec = p.vec;
				int A, B, C, D;
				
				if(rand() % 2) {
					A = rand() % n;
					B = A;
					C = rand() % (n - l[i] + 1);
					D = C + l[i] - 1;
				} else {
					C = rand() % n;
					D = C;
					A = rand() % (n - l[i] + 1);
					B = A + l[i] - 1;
				}
				
				for(int i = A; i < B; i++) seg[i].reverse(C, D);				
				int newscore = -count;
				for(int i = 0; i < n; i++) newscore += seg[i].get(0, n + 1);
				vec.push_back(std::tuple<int, int, int, int>(A + 1, C + 1, B + 1, D + 1));
				Node Np = Node{newscore, seg, vec};
				qu[1 - i % 2].push(Np);
				
				if(qu[1 - i % 2].size() > K) qu[1 - i % 2].pop();
			}
		}
	}
	
	Node p;
	while(!qu[k % 2].empty()) {
		p = qu[k % 2].top(); qu[k % 2].pop();
	}
	
	for(auto v : p.vec) cout << std::get<0>(v) << " " << std::get<1>(v) << " " << std::get<2>(v) << " " << std::get<3>(v) << endl;
	return 0;
}
0