codeforces 948D

Perfect Security

给2个长度为n的数组a, p, 改变p顺序,使得a^p 得出来的数组字典序最小

思路: 以p数组建字典树, 然后每次找与ai最“接近”的数(即俩数异或最小, 每次再从字典树中删除该数即可

#include "iostream"
#include "iomanip"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#pragma comment(linker, "/STACK:102400000,102400000")
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a,x) memset(a,x,sizeof(a))
#define step(x) fixed<< setprecision(x)<<
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define ll long long
#define endl ("\n")
#define ft first
#define sd second
#define lrt (rt<<1)
#define rrt (rt<<1|1)
using namespace std;
const ll mod=1e9+7;
const ll INF = 1e18+1LL;
const int inf = 1e9+1e8;
const double PI=acos(-1.0);
const int N=1e5+100;

int tree[N*50][2], data[N*50][2];
int a[N*3], p[N*3], n, tot=1, root=1;

void Insert(int x) {
    int now = root, num[31];
    for(int i=30; i>=0; --i) {
        num[i] = x&1;
        x >>= 1;
    }
    for(int i=0; i<=30; ++i) {
        int t = num[i];//cout<<t<<endl;
        if(tree[now][t]) data[now][t]++;
        else{
            tree[now][t] = ++tot;
            data[now][t] = 1;
        }
        now = tree[now][t];
    }
}

void del(int x) {
    int now = root, num[31];
    for(int i=30; i>=0; --i) {
        num[i] = x&1;
        x >>= 1;
    }
    for(int i=0; i<=30; ++i) {
        int t = num[i];
        data[now][t]--;
        now = tree[now][t];
        if(!data[now][t]) tree[now][t] = 0;
    }
}

int finds(int x) {
    int now = root, r = 1, ret = 0;
    int num[31];
    for(int i=30; i>=0; --i) {
        num[i] = x&1;
        x >>= 1;
    }
    for(int i=0; i<=30; ++i) {
        int t = num[i];
        if(data[now][t]) {
            ret *= 2;
            ret += t;
            now = tree[now][t];
        }
        else {
            ret *= 2;
            ret += t^1;
            now = tree[now][t^1];
        }
    }
    return ret;
}
int main() {
    scanf("%d", &n);
    for(int i=1; i<=n; ++i) {
        scanf("%d", &a[i]);
    }
    for(int i=1; i<=n; ++i) {
        scanf("%d", &p[i]);
        Insert(p[i]);
    }//cout<<tot<<endl;
    for(int i=1; i<=n; ++i){
        int x = finds(a[i]);
        del(x);
        printf("%d ", x^a[i]);
    }

    return 0;
}

 

posted on 2018-03-17 22:45  lazzzy  阅读(365)  评论(0编辑  收藏  举报

导航