一個數列\(A\),數的範圍均在\([0, 2^N-1]\)內,求一個\(B\),使得新生成的數列\(C\)中逆序對最多(\(C_i = A_i xor B\)),輸出最多的逆序對。(\(|A|<=10^5\))node
這種題固然要逐位考慮..考慮到二進制和xor,咱們須要想到trie...c++
將數列插入到一棵trie,咱們在每個層記錄一個信息,表示\(B\)在這一層取\(0\)或取\(1\)新增的逆序對數,而後統計答案便可。
而因爲是xor操做,因此很好統計,咱們能夠每插入一個數就統計一次。spa
// BEGIN CUT HERE // END CUT HERE #line 5 "XorSequence.cpp" #include <bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back const int N=150005; struct node { node *c[2]; int s; void init() { c[0]=c[1]=0; s=0; } }Po[N*31], *iT=Po, *root=0; ll c[31][2]; node *newnode() { iT->init(); return iT++; } void add(int w, int dep=29, node *&x=root) { if(!x) { x=newnode(); } ++x->s; if(dep<0) { return; } int f=(w>>dep)&1; if(f) { add(w, dep-1, x->c[1]); if(x->c[0]) { c[dep][0]+=x->c[0]->s; } } else { add(w, dep-1, x->c[0]); if(x->c[1]) { c[dep][1]+=x->c[1]->s; } } } class XorSequence { public: long long getmax(int N, int sz, int A0, int A1, int P, int Q, int R) { iT=Po; root=0; memset(c, 0, sizeof c); add(A0); for(int i=1; i<sz; ++i) { add(A1); int t=A1; A1=(1ll*A0*P+1ll*A1*Q+R)%N; A0=t; } ll ans=0; for(int i=0; i<30; ++i) { ans+=max(c[i][0], c[i][1]); } return ans; } // BEGIN CUT HERE public: void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); if ((Case == -1) || (Case == 5)) test_case_5(); } private: template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } void verify_case(int Case, const long long &Expected, const long long &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } } void test_case_0() { int Arg0 = 4; int Arg1 = 6; int Arg2 = 3; int Arg3 = 2; int Arg4 = 0; int Arg5 = 1; int Arg6 = 3; long long Arg7 = 8LL; verify_case(0, Arg7, getmax(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)); } void test_case_1() { int Arg0 = 8; int Arg1 = 8; int Arg2 = 2; int Arg3 = 5; int Arg4 = 3; int Arg5 = 1; int Arg6 = 4; long long Arg7 = 13LL; verify_case(1, Arg7, getmax(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)); } void test_case_2() { int Arg0 = 8; int Arg1 = 7; int Arg2 = 3; int Arg3 = 0; int Arg4 = 1; int Arg5 = 2; int Arg6 = 4; long long Arg7 = 12LL; verify_case(2, Arg7, getmax(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)); } void test_case_3() { int Arg0 = 32; int Arg1 = 15; int Arg2 = 7; int Arg3 = 9; int Arg4 = 11; int Arg5 = 2; int Arg6 = 1; long long Arg7 = 60LL; verify_case(3, Arg7, getmax(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)); } void test_case_4() { int Arg0 = 131072; int Arg1 = 131072; int Arg2 = 7; int Arg3 = 7; int Arg4 = 1; int Arg5 = 0; int Arg6 = 0; long long Arg7 = 0LL; verify_case(4, Arg7, getmax(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)); } void test_case_5() { int Arg0 = 131072; int Arg1 = 131070; int Arg2 = 411; int Arg3 = 415; int Arg4 = 398; int Arg5 = 463; int Arg6 = 9191; long long Arg7 = 4302679760LL; verify_case(5, Arg7, getmax(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)); } // END CUT HERE }; // BEGIN CUT HERE int main() { XorSequence ___test; ___test.run_test(-1); return 0; } // END CUT HERE