Codeforces1300C-Anu Has a Function
定义一个函数f(x,y), f(x,y) = x|y - y,给你一个数列,a1,a2,,an问如何排列能使f(f(f(a1,a2),a3),````,an)答案最大,我们将f(x,y)变形,就是f(x,y)=x&(~y),那么答案的大小只与第一个选取的x有关,其余都是取反交,那我们只要找出一个最大的x,让他的最高位为1,其他数的该位为0,这样下来答案至少就是该位对应的二进制码,例如 01010, 10000, 10001,我们就选择01010为最大,答案至少就为01000,根据数据限制,位数最多为30,时间复杂度就是O(30*1e5)
#include<bits/stdc++.h> using namespace std; #define lowbit(x) ((x)&(-x)) typedef long long LL; int bit[33]; void getbit(int x) { int cnt = 0; while(x) { if(x&1) bit[cnt]++; cnt++; x/=2; } } void run_case() { int n; cin >> n; vector<int> buf(n); for(int i = 0; i < n; ++i) { cin >> buf[i]; getbit(buf[i]); } for(int k = 30; k >= 0; --k) if(bit[k] == 1) { for(int i = 0; i < n; ++i) if(buf[i]&(1<<k)) { cout << buf[i] << " "; for(int j = 0; j < n; ++j) if(j != i) cout << buf[j] << " "; return; } } for(auto c:buf) cout << c << " "; } int main() { ios::sync_with_stdio(false), cin.tie(0); //int t; cin >> t; //while(t--) run_case(); cout.flush(); return 0; }