codeforces D. Perfect Security
阿新 • • 發佈:2019-01-30
題意:給出兩個序列a,b,找出b的某一種置換,求出字典序最小的序列c,滿足ci=ai^bi。
對於每一個ai,我們只要找出序列b中可用元素中異或結果最小的那一個,就可以保證字典序最小了。對b中的每一個建立出
01字典樹,再將ai代入查詢即可。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxm = 300005; int a[maxm], m, b[maxm]; typedef struct trie { trie *next[2]; int s; trie() { next[0] = next[1] = NULL; s= 0; } }trie; trie *root = new trie; void insert(int k) { trie *p = root, *q; for (int i = 30;i >= 0;i--) { int id = (k&(1 << i)) != 0; if (p->next[id] == NULL) { q = new trie; p->next[id] = q; p = p->next[id]; p->s++; } else { p = p->next[id]; p->s++; } } } int find(int k) { int ans = 0; trie *p = root, *q, *temp; for (int i = 30;i >= 0;i--) { int id = (k&(1 << i)) != 0; if (p->next[id]!=NULL && p->next[id]->s > 0) { p->next[id]->s--; p = p->next[id]; } else { ans |= 1 << i; p->next[id^1]->s--; p = p->next[id^1]; } } return ans; } int main() { int n, i, j, k, sum; scanf("%d", &n); for (i = 1;i <= n;i++) scanf("%d", &a[i]); for (i = 1;i <= n;i++) { scanf("%d", &b[i]); insert(b[i]); } for (i = 1;i <= n;i++) { int ans = find(a[i]); printf("%d ", ans); } printf("\n"); return 0; }