首页 > 代码库 > ifrog-1028 Bob and Alice are playing numbers(trie树)

ifrog-1028 Bob and Alice are playing numbers(trie树)

题目链接:

Bob and Alice are playing numbers

DESCRIPTION
Bob and his girl friend are playing game together.This game is like this: There are nn numbers. If op = 11,Bob wants to find two numbers aiai and ajaj,that aiai & ajaj will become maximum value. If op = 22,Bob wants to find two numbers aiai and ajaj,that aiai ^ ajaj will become maximum value. If op = 33,Bob wants to find two numbers aiai and ajaj,that aiai | ajaj will become maximum value. Notice: & for bitwise AND. (4 & 2) is 0, (4 & 5) is 4. ^ for bitwise XOR. (4 ^ 2) is 6, (4 ^ 5) is 1. | for bitwise OR . (4 | 2) is 6, (4 | 5) is 5.
INPUT
First line is a positive integer TT , represents there are TT test cases. For each test case: First line includes two numbers n(2n100000),op(1op3)n(2≤n≤100000),op(1≤op≤3). The next line contains nn numbers: a1,a2,...,an(1ai1000000)a1,a2,...,an(1≤ai≤1000000).
OUTPUT
For the ii-th test case , first output Case #i: in a single line. Then output the answer of ii-th test case.
SAMPLE INPUT
 
3
2 1
4 2
2 2
4 2
2 3
4 2
SAMPLE OUTPUT
 
Case #1: 0
Case #2: 6
Case #3: 6
 
题意:
 
^ & |三种操作找到能得到的最大值;
 
思路:
 
异或的值就是经典的trie树,&可以转化成trie树上的贪心,|也是一个贪心了,对于一个数x[i],那么就找它所有为0的位置,看最大能贪心多少;
 
AC代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <bits/stdc++.h>#include <stack>#include <map>  using namespace std;  #define For(i,j,n) for(int i=j;i<=n;i++)#define mst(ss,b) memset(ss,b,sizeof(ss));  typedef  long long LL;  template<class T> void read(T&num) {    char CH; bool F=false;    for(CH=getchar();CH<‘0‘||CH>‘9‘;F= CH==‘-‘,CH=getchar());    for(num=0;CH>=‘0‘&&CH<=‘9‘;num=num*10+CH-‘0‘,CH=getchar());    F && (num=-num);}int stk[70], tp;template<class T> inline void print(T p) {    if(!p) { puts("0"); return; }    while(p) stk[++ tp] = p%10, p/=10;    while(tp) putchar(stk[tp--] + ‘0‘);    putchar(‘\n‘);}  const int mod=1e9+7;const double PI=acos(-1.0);const int inf=1e9;const int N=(1<<20)+10;const int maxn=1e5+110;const double eps=1e-12; int ch[21*maxn][2],sz,val[21*maxn],s[23],dp[21],x[maxn],n;bool vis[N*2];void insert(int x){    mst(s,0);    int n=0,u=0;    while(x)s[n++]=(x&1),x>>=1;    for(int i=20;i>=0;i--)    {        int c=s[i];        if(!ch[u][c])        {            ch[sz][0]=ch[sz][1]=0;            ch[u][c]=sz++;        }        u=ch[u][c];        val[u]++;    }}inline int query_or(){    memset(vis,false,sizeof(vis));    For(i,1,n)vis[x[i]]=true;    for(int i=(1<<20);i>0;i--)    {        for(int j=0;j<=20;j++)        {            if(!(i&(1<<j)))vis[i]|=vis[i|(1<<j)];        }    }    int ans=0,t[22];    for(int i=1;i<=n;i++)    {        int num=0,temp=0;        for(int j=20;j>=0;j--)        {            if(!(x[i]&(1<<j)))t[num++]=(1<<j);        }        for(int j=0;j<num;j++)        {            if(vis[temp|t[j]])temp|=t[j];        }        ans=max(ans,temp|x[i]);    }    return ans;}void same(int &l,int r){    if(!r)return ;    if(!l)    {        ch[sz][0]=ch[sz][1]=0;        l=sz++;    }    val[l]+=val[r];    same(ch[l][0],ch[r][0]);    same(ch[l][1],ch[r][1]);}inline int query_and(){    int u=0,ans=0;    for(int i=20;i>=0;i--)    {        if(val[ch[u][1]]>=2)u=ch[u][1],ans|=dp[i];        else same(ch[u][0],ch[u][1]),u=ch[u][0];    }    return ans;}inline int query_xor(int x){    mst(s,0);    int n=0,u=0,ans=0;    while(x)s[n++]=(x&1),x>>=1;    for(int i=20;i>=0;i--)    {        int c=s[i];        if(ch[u][c^1])ans|=dp[i],u=ch[u][c^1];        else u=ch[u][c];    }    return ans;}inline void Init(){    sz=1;    mst(ch[0],0);    mst(val,0);    for(int i=0;i<=20;i++)        dp[i]=(1<<i);}int main(){      int t,Case=0;      read(t);      while(t--)      {            int op,ans=0;            read(n);read(op);            Init();            read(x[1]);insert(x[1]);            For(i,2,n)            {                read(x[i]);                if(op==2)ans=max(ans,query_xor(x[i]));                if(op<3)insert(x[i]);            }            if(op==1)ans=query_and();            else if(op==3)ans=query_or();            printf("Case #%d: %d\n",++Case,ans);      }    return 0;}

  

ifrog-1028 Bob and Alice are playing numbers(trie树)