QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#558283#7411. Bitwise Xorhmya#WA 1ms6004kbC++142.9kb2024-09-11 15:18:222024-09-11 15:18:23

Judging History

你现在查看的是最新测评结果

  • [2024-09-11 15:18:23]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:6004kb
  • [2024-09-11 15:18:22]
  • 提交

answer

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,K;
int ans=1;
const int P=998244353;
class trie01{
    public:
    int ch[300005<<5][2];
    int siz[300005<<5];
    int tot;
    void insert(int x){
        int now=0;
        // siz[0]++;
        for(int i=60;i>=0;i--){
            int nxt=((x>>i)&1);
            if(!ch[now][nxt])ch[now][nxt]=++tot;
            now=ch[now][nxt];
            siz[now]++;
        }
        return;
    }
    int getans(int X,int Y,int k){
        // printf("getans %lld %lld %lld\n",X,Y,k);
        if(!X||!Y)return 0;
        if(k==-1){//
            return siz[X]*siz[Y]%P;
        }
        if((K>>k)&1){//考虑第二高的位,如果当前是1,那就只能是X的左儿子匹配Y的右儿子了!
        //只判断选出两个数来的方案,只选一个数或是不选什么的我在里面也能判
            // printf("muled %lld %lld %lld %lld\n",siz[ch[X][0]],siz[ch[Y][1]],siz[ch[X][1]],siz[ch[Y][0]]);
            return (siz[ch[X][0]]*siz[ch[Y][1]]+siz[ch[X][1]]*siz[ch[Y][0]])%P;
        }
        return (getans(ch[X][0],ch[Y][0],k-1)+getans(ch[X][1],ch[Y][1],k-1))%P;
    }
    void search(int cur,int k){
        // if(!cur)return;
        if((K>>k)&1){//k是highbit表示这里面只能选一个
            // printf("k=%lld ",k);
            if(!ch[cur][0]){
                (ans*=(siz[ch[cur][1]]+1))%=P;
                // printf("mul1 %lld\n",siz[ch[cur][1]]+1);
            }
            else if(!ch[cur][1]){
                (ans*=(siz[ch[cur][0]]+1))%=P;
                // printf("mul2 %lld\n",siz[ch[cur][0]]+1);
            }
            else{
                if(K^(1<<k)){//
                    int mul=(getans(ch[cur][0],ch[cur][1],k-1)+siz[cur]+1);
                    (ans*=mul)%=P;
                    // printf("mul3 %lld\n",mul);
                }
                else{
                    int mul=(siz[ch[cur][0]]*siz[ch[cur][1]]+siz[cur]+1)%P;
                    (ans*=mul)%=P;
                    // printf("mul4 %lld\n",mul);
                }
            }
            return;
        }
        if(ch[cur][0])search(ch[cur][0],k-1);
        if(ch[cur][1])search(ch[cur][1],k-1);
        return;
    }
}T;
signed main(){
    scanf("%lld%lld",&n,&K);
    for(int i=1;i<=n;i++){
        int x;
        scanf("%lld",&x);
        T.insert(x);
    }
    if(K==0){//乱选
        printf("%lld\n",((1ll<<n)-1)%P);
        return 0;
    }
    T.search(0,60);
    printf("%lld\n",ans-1);
    return 0;
}
/*
要求选出一个集合使得里面的数两两xor最小值不比x小。

建01trie

找到K的highbit

限制变成了:当前子树只能选一个的方案数

然后考虑,自上而下,这一位恰好为1的选择方案数,那就是找到第二个highbit,在这一层,只有在不同子树的才能选。

没有下一个了。
*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 5808kb

input:

3 0
0 1 2

output:

7

result:

ok 1 number(s): "7"

Test #2:

score: 0
Accepted
time: 1ms
memory: 5932kb

input:

3 2
0 1 2

output:

5

result:

ok 1 number(s): "5"

Test #3:

score: 0
Accepted
time: 1ms
memory: 5848kb

input:

3 3
0 1 2

output:

4

result:

ok 1 number(s): "4"

Test #4:

score: 0
Accepted
time: 1ms
memory: 5932kb

input:

7 4
11 5 5 8 3 1 3

output:

35

result:

ok 1 number(s): "35"

Test #5:

score: 0
Accepted
time: 1ms
memory: 5936kb

input:

10 0
1 1 0 0 1 0 0 0 1 1

output:

1023

result:

ok 1 number(s): "1023"

Test #6:

score: 0
Accepted
time: 1ms
memory: 6004kb

input:

10 0
1 1 0 1 0 1 1 0 1 0

output:

1023

result:

ok 1 number(s): "1023"

Test #7:

score: 0
Accepted
time: 1ms
memory: 5924kb

input:

10 1
1 0 0 1 0 0 0 0 0 0

output:

26

result:

ok 1 number(s): "26"

Test #8:

score: 0
Accepted
time: 1ms
memory: 5936kb

input:

10 0
0 0 1 1 0 1 1 1 1 1

output:

1023

result:

ok 1 number(s): "1023"

Test #9:

score: 0
Accepted
time: 1ms
memory: 5812kb

input:

10 1
0 0 0 0 0 1 1 0 0 1

output:

31

result:

ok 1 number(s): "31"

Test #10:

score: 0
Accepted
time: 1ms
memory: 5856kb

input:

10 2
3 3 3 0 3 1 2 2 1 2

output:

31

result:

ok 1 number(s): "31"

Test #11:

score: 0
Accepted
time: 1ms
memory: 5940kb

input:

10 0
2 1 1 1 1 2 0 1 2 0

output:

1023

result:

ok 1 number(s): "1023"

Test #12:

score: 0
Accepted
time: 1ms
memory: 5928kb

input:

10 1
2 2 2 3 2 3 3 1 2 3

output:

59

result:

ok 1 number(s): "59"

Test #13:

score: 0
Accepted
time: 1ms
memory: 5856kb

input:

10 0
0 0 0 1 1 1 0 2 3 2

output:

1023

result:

ok 1 number(s): "1023"

Test #14:

score: 0
Accepted
time: 1ms
memory: 5940kb

input:

10 3
0 2 2 2 1 2 3 0 2 1

output:

22

result:

ok 1 number(s): "22"

Test #15:

score: 0
Accepted
time: 1ms
memory: 5932kb

input:

10 232612786
899206785 627708234 142071418 602920154 868777585 1041571266 892732172 868993257 746093759 987356899

output:

109

result:

ok 1 number(s): "109"

Test #16:

score: 0
Accepted
time: 1ms
memory: 5872kb

input:

10 0
693036642 1030693062 419968059 741209191 591827389 259645735 276712455 734217910 177798129 94619093

output:

1023

result:

ok 1 number(s): "1023"

Test #17:

score: -100
Wrong Answer
time: 0ms
memory: 5848kb

input:

10 635603548
611293890 811243506 517958533 561419149 895889603 689314144 76814806 428189482 659398653 905893003

output:

11

result:

wrong answer 1st numbers differ - expected: '28', found: '11'