結果
| 問題 |
No.5001 排他的論理和でランニング
|
| ユーザー |
treeone
|
| 提出日時 | 2018-03-17 02:55:11 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,486 ms / 1,500 ms |
| コード長 | 3,803 bytes |
| コンパイル時間 | 2,145 ms |
| 実行使用メモリ | 15,212 KB |
| スコア | 51,375,666 |
| 最終ジャッジ日時 | 2020-03-12 19:57:44 |
|
ジャッジサーバーID (参考情報) |
judge7 / |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 50 |
ソースコード
#include <bits/stdc++.h>
#define rep(i, a, n) for(int i = a; i < n; i++)
#define REP(i, n) rep(i, 0, n)
#define repb(i, a, b) for(int i = a; i >= b; i--)
#define all(a) a.begin(), a.end()
#define int long long
#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)
using namespace std;
typedef pair<int, int> P;
const int mod = 1000000007;
const int INF = 1e12;
unsigned w;
unsigned xor128() {
static unsigned x = 123456789, y = 362436069, z = 521288629/*, w = 88675123*/;
unsigned t = (x ^ (x << 11));
x = y; y = z; z = w;
return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}
class Timer {
private:
clock_t start;
public:
Timer() {
start = clock();
}
double sec() {
clock_t end = clock();
return (double) (end - start) / CLOCKS_PER_SEC;
}
};
const double TimeLimit = 1.450;
Timer timer;
void display(int now){
repb(i, 19, 0){
if(now & (1LL << i)) cerr << "1";
else cerr << "0";
}
cerr << endl;
return;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
clock_t start, end;
start = clock();
random_device rnd;
mt19937 mt((int)time(0));
w = mt();
int n, m;
cin >> n >> m;
vector<int> a(n);
vector<int> d[20], e[20];
rep(i, 0, n){
cin >> a[i];
}
sort(all(a));
rep(i, 0, n){
bool f = true;
repb(j, 19, 0){
if(a[i] & (1LL << j)){
if(f){
d[j].push_back(i);
f = false;
}
e[j].push_back(i);
}
}
}
// vector<int> ans;
set<int> st;
int now = 0;
repb(i, 19, 0){
if(st.size() == m) break;
int sz = m - (int)st.size();
int limit = min(sz / 2, (int)d[i].size());
if(now & (1LL << i)){
if(limit % 2) limit--;
}else{
if(limit % 2 == 0) limit--;
}
cerr << i << " " << limit << " " << (now & (1LL << i)) << " ";
rep(j, 0, limit){
now ^= a[d[i][j]];
st.insert(d[i][j]);
}
cerr << (now & (1LL << i)) << endl;
}
cerr << st.size() << " " << now << endl;
display(now);
cerr << m - st.size() << endl;
rep(i, 0, 20){
rep(j, 0, d[i].size()){
if(st.size() == m) break;
if(!st.count(d[i][j])){
now ^= a[d[i][j]];
// ans.push_back(i);
st.insert(d[i][j]);
}
}
}
cerr << st.size() << " " << now << endl;
display(now);
int cnt = 0, grow = 0, high = -1;
while(1){
double tmp = timer.sec();
if(tmp > TimeLimit){
break;
}
// if(high == -1){
// repb(i, 19, 0){
// if(now & (1LL << i)) continue;
// high = i; break;
// }
// if(high == -1) break;
// }
int id = xor128() % n;
// if(!st.count(id)) continue;
// if(d[high].size() == 0) continue;
// int id2 = xor128() % (int)(d[high].size());
// if(st.count(id2)) continue;
// id2 = d[high][id2];
int id2 = xor128() % n;
if(!(st.count(id) ^ st.count(id2))) continue;
if(st.count(id2)) swap(id, id2);
cnt++;
int tmp2 = now ^ a[id] ^ a[id2];
if(tmp2 > now){
now = tmp2;
st.erase(id);
st.insert(id2);
grow++;
}
// if((int)(tmp * 1000) % 1000 <= 20){
// cerr << tmp << " " << now << endl;
// }
}
int sum = 0;
for(auto it = st.begin(); it != st.end(); it++){
if(it != st.begin()) cout << ' ';
cout << a[*it];
sum ^= a[*it];
}
cout << endl;
cerr << now << " " << sum << " " << cnt << " " << grow << endl;
display(now);
}
treeone