Beautiful Subarrays

E. Beautiful Subarrays
One day, ZS the Coder wrote down an array of integers a with elements a1,  a2,  ...,  an.
A subarray of the array a is a sequence al,  al  +  1,  ...,  ar for some integers (l,  r) such that 1  ≤  l  ≤  r  ≤  n. ZS the Coder thinks that a subarray of a is beautiful if the bitwise xor of all the elements in the subarray is at least k.
Help ZS the Coder find the number of beautiful subarrays of a!
Input
The first line contains two integers n and k (1 ≤ n ≤ 106, 1 ≤ k ≤ 109) — the number of elements in the array a and the value of the parameter k.
The second line contains n integers ai (0 ≤ ai ≤ 109) — the elements of the array a.
Output
Print the only integer c — the number of beautiful subarrays of the array a.
Examples
Input
3 1
1 2 3

Output
5

Input
3 2
1 2 3

Output
3

Input
3 3
1 2 3

Output
2

제목: 제목 은 n 개의 부정 정수 가 아 닌 배열 을 주 는 것 입 니 다. 이 배열 에 몇 개의 키 구간 이 있 는 지, 구간 의 차이 점 이나 적어도 k 가 있 는 지 구 합 니 다.
문제 풀이: 이 또는 화 를 보면 사전 트 리 가 연상 된다.
그것 이 k 보다 큰 지 여 부 는 그들의 2 진 위 치 를 비교 할 수 있다. 정수 가 최대 1e9 이기 때문에 최대 31 번 을 비교 할 수 있다. 그 다음 에 분류 토론 을 통 해 다음 과 같다. j 번 째 2 진 위치 에 대해 k & (1 < 0 이면 보장 해 야 한다.
i 번 째 수의 끝 구간 이 다 르 거나 j 번 째 바 이 너 리 에서 도 1. 반대로 0. 이 를 알 면 이 또는 접두사 와 몇 개의 구간 이 이러한 상황 을 만족 시 키 는 지 찾 을 수 있 습 니 다. 그러나 순 전 히 매 거 진 시간 복잡 도 는 n ^ 2 * 입 니 다.
30 의 경우 데이터 구조 사전 나 무 를 통 해 복잡 도 를 최적화 할 수 있 고 시간 복잡 도 는 n * 30 으로 낮 출 수 있 습 니 다. 그러면 문 제 는 1s 이내 에 달 려 갈 수 있 습 니 다. 문 제 는 3s 에 게 주 었 으 니 양심 적 입 니 다.
AC 코드:
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

typedef long long ll;
const int N = 3e7 + 5;
int tot;

struct Node
{
    int val;
    int next[2];
    void init()
    {
        val = 0;
        memset(next,0,sizeof next);
    }
}tree[N];

void Insert(int x)
{
    int pos = 0;
    for(int i = 30; i >= 0; --i)
    {
        int v = (x & (1 << i)) ? 1 : 0;
        if(!tree[pos].next[v])
        {
            tree[++tot].init();
            tree[pos].next[v] = tot;
        }
        pos = tree[pos].next[v];
        ++tree[pos].val;
    }
}

int Find(int x,int k)
{
    int cnt,pos;
    cnt = pos = 0;
    for(int i = 30; i >= 0; --i)
    {
        int v = (x & (1 << i)) ? 1 : 0;
        if(k & (1 << i))
        {
            pos = tree[pos].next[v ^ 1];
        }
        else
        {
            int tp = tree[pos].next[v ^ 1];
            pos = tree[pos].next[v];
            cnt += tree[tp].val;
        }
        if(pos == 0)
            break;
        if(i == 0)
            cnt += tree[pos].val;
    }
    return cnt;
}

void solve()
{
    int n,k,temp,x;
    ll ans = 0;
    scanf("%d %d",&n,&k);
    tot = temp = 0;
    tree[tot].init();
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d",&x);
        Insert(temp);
        temp ^= x;
        ans += Find(temp,k);
    }
    cout << ans << endl;
}


int main()
{
    solve();
    return 0;
}

좋은 웹페이지 즐겨찾기