zoukankan      html  css  js  c++  java
  • 双01字典树最小XOR(three arrays)--2019 Multi-University Training Contest 5(hdu杭电多校第5场)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6625

    题意:

    给你两串数 a串,b串,让你一一配对XOR使得新的 C 串字典序最小。

    思路:

    首先这边有两个问题:

    1. 我要怎么知道这两个数配对是最优的:一开始我也不明白(以为选择会有后效性),其实很简单,对 a 里的一个X,在 b 的01树里跑到的最优解Y也一定就是 b 的这个Y在 a 的01树里跑到的最优解X

    2. 如果现在两颗树里跑到的点的下一个只有一种选择的话,肯定就接着跑,但是如果现在两个点的下两个点都有01,那大家跑0还是跑1呢?其实随便选一个就行了,因为你下一次还是会跑另一个数的,虽然不是每次都找到 C 串里的头一个最小值,但是跑完sort一下就行了答案都是会在里面的)。

      1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
      2 #include <cstdio>//sprintf islower isupper
      3 #include <cstdlib>//malloc  exit strcat itoa system("cls")
      4 #include <iostream>//pair
      5 #include <fstream>
      6 #include <bitset>
      7 //#include <map>
      8 //#include<unordered_map>   http://acm.hdu.edu.cn/showproblem.php?pid=6625
      9 #include <vector>
     10 #include <stack>
     11 #include <set>
     12 #include <string.h>//strstr substr
     13 #include <string>
     14 #include <time.h>//srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
     15 #include <cmath>
     16 #include <deque>
     17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
     18 #include <vector>//emplace_back
     19 //#include <math.h>
     20 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
     21 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
     22 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
     23 #define fo(a,b,c) for(register int a=b;a<=c;++a)
     24 #define fr(a,b,c) for(register int a=b;a>=c;--a)
     25 #define mem(a,b) memset(a,b,sizeof(a))
     26 #define pr printf
     27 #define sc scanf
     28 #define ls rt<<1
     29 #define rs rt<<1|1
     30 void swapp(int &a,int &b);
     31 double fabss(double a);
     32 int maxx(int a,int b);
     33 int minn(int a,int b);
     34 int Del_bit_1(int n);
     35 int lowbit(int n);
     36 int abss(int a);
     37 //const long long INF=(1LL<<60);
     38 const double E=2.718281828;
     39 const double PI=acos(-1.0);
     40 const int inf=(1<<29);
     41 const double ESP=1e-9;
     42 const int N=(int)31e5+10;
     43 int read(){
     44     int x=0,f=1;char ch=getchar();
     45     for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
     46     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
     47     return x*f;
     48 }
     49 int n;
     50 struct Trie
     51 {
     52     int tr[N][2],val[N],sz[N][2],rt,tot;
     53     void init()
     54     {
     55         rt=tot=0;
     56         for(int i=0;i<=n*31;++i)
     57             tr[i][0]=tr[i][1]=val[i]=sz[i][0]=sz[i][1]=0;
     58     }
     59     void insert(int x)
     60     {
     61         rt=0;
     62         for(int i=30;i>=0;--i)
     63         {
     64             int id=(x>>i)&1;
     65             if(!tr[rt][id]) tr[rt][id]=++tot;
     66             ++sz[rt][id];
     67             rt=tr[rt][id];
     68         }
     69         val[rt]=x;
     70     }
     71 }a,b;
     72 
     73 int ans[100005];
     74 int search(int rt1,int rt2)
     75 {
     76     while(1)//写成递归可能会TLE;
     77     {
     78         if(a.val[rt1]||b.val[rt2])
     79             return a.val[rt1]^b.val[rt2];
     80         if(a.sz[rt1][1]&&b.sz[rt2][1])// 有同11/00就走
     81         {
     82             --a.sz[rt1][1];--b.sz[rt2][1];
     83             rt1=a.tr[rt1][1],rt2=b.tr[rt2][1];
     84             continue;
     85         }
     86         if(a.sz[rt1][0]&&b.sz[rt2][0])
     87         {
     88             --a.sz[rt1][0];--b.sz[rt2][0];
     89             rt1=a.tr[rt1][0],rt2=b.tr[rt2][0];
     90             continue;
     91         }
     92         int to1,to2;
     93         to1=a.sz[rt1][0]?0:1;//实在没有相同的能走就走;
     94         to2=b.sz[rt2][0]?0:1;
     95         --a.sz[rt1][to1],--b.sz[rt2][to2];
     96         rt1=a.tr[rt1][to1],rt2=b.tr[rt2][to2];
     97     }
     98 }
     99 
    100 int main()
    101 {
    102     int T;
    103     T=read();
    104     while(T--)
    105     {
    106         n=read();
    107         a.init();b.init();
    108         for(int i=1;i<=n;++i)
    109         {
    110             int t;
    111             t=read();
    112             a.insert(t);
    113         }
    114         for(int i=1;i<=n;++i)
    115         {
    116             int t;
    117             t=read();
    118             b.insert(t);
    119         }
    120         for(int i=1;i<=n;++i)
    121             ans[i]=search(0,0);
    122         sort(ans+1,ans+1+n);
    123         for(int i=1;i<=n;++i)
    124             printf("%d%c",ans[i],i==n?'
    ':' ');
    125     }
    126     return 0;
    127 }
    128 
    129 /**************************************************************************************/
    130 
    131 int maxx(int a,int b)
    132 {
    133     return a>b?a:b;
    134 }
    135 
    136 void swapp(int &a,int &b)
    137 {
    138     a^=b^=a^=b;
    139 }
    140 
    141 int lowbit(int n)
    142 {
    143     return n&(-n);
    144 }
    145 
    146 int Del_bit_1(int n)
    147 {
    148     return n&(n-1);
    149 }
    150 
    151 int abss(int a)
    152 {
    153     return a>0?a:-a;
    154 }
    155 
    156 double fabss(double a)
    157 {
    158     return a>0?a:-a;
    159 }
    160 
    161 int minn(int a,int b)
    162 {
    163     return a<b?a:b;
    164 }
  • 相关阅读:
    sublime c/c++ 环境
    sublime编写markdownm
    第八次课程作业
    第七次课程作业
    第六次作业
    第五次课程作业
    Arithmatic项目修改总结
    第四次课程作业
    第三次课程作业
    课程作业二
  • 原文地址:https://www.cnblogs.com/--HPY-7m/p/11348794.html
Copyright © 2011-2022 走看看