結果

問題 No.3569 Xor to Zero
コンテスト
ユーザー Aob-11
提出日時 2026-08-21 12:10:10
言語 C++23(gcc16)
(gcc 16.1.0 + boost 1.90.0)
コンパイル:
g++-16 -O2 -lm -std=c++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
AC  
実行時間 217 ms / 2,000 ms
+ 199µs
コード長 6,007 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 2,527 ms
コンパイル使用メモリ 355,548 KB
実行使用メモリ 18,560 KB
最終ジャッジ日時 2026-08-21 12:10:21
合計ジャッジ時間 8,300 ms
ジャッジサーバーID
(参考情報)
judge2_0 / judge1_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 25
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <bits/stdc++.h>



using namespace std;

#define DB double
#define LL long long
#define ULL unsigned long long
#define uint unsigned int
#define in128 int128
#define cint const int
#define cLL const LL
#define For(z,e1,e2) for(int z=(e1);z<=(e2);z++)
#define Rof(z,e1,e2) for(int z=(e2);z>=(e1);z--)

#define inint(e) scanf("%d",&e)
#define inll(e) scanf("%lld",&e)
#define inpr(e1,e2) scanf("%d%d",&e1,&e2)
#define in3(e1,e2,e3) scanf("%d%d%d",&e1,&e2,&e3)
#define outint(e) printf("%d\n",e)
#define outll(e) printf("%lld\n",e)
#define exc(e) if(e) continue
#define stop(e) if(e) break
#define ret(e) if(e) return
#define pb push_back
#define ft first
#define sc second
#define pii pair<int,int>
#define pli pair<long long,int>
#define pil pair<int,long long>
#define vct vector
#define clean(e) while(!e.empty()) e.pop()
#define all(ev) ev.begin(),ev.end()
#define sz(ev) ((int)ev.size())

cLL mod=998244353ll,G=404ll;
template <typename Type> void get_min(Type &w1,const Type w2) { if(w2<w1) w1=w2; } 
template <typename Type> void get_max(Type &w1,const Type w2) { if(w2>w1) w1=w2; }
template <typename Type> Type md(Type w1,const Type w2=mod) { w1%=w2; if(w1<(Type)0) w1+=w2; return w1; } 
void Add(LL &X_,cLL Y_,cLL M_=mod) { if((X_+=Y_)>=M_) X_-=M_; }

mt19937 gen(time(NULL));
int rnd(int l,int r) { return (int)(gen()%(r-l+1)+l); }
mt19937_64 genll(time(NULL));
LL rndll(LL l,LL r) { return (LL)(genll()%(r-l+1ll)+l); }

void main_init()
{

}

cint MAX_NODES = 4000005; 
cint MAX_BIT = 30;

struct Node {
    int ch[2];
    int sz;
    int add_x;
    int set_x;
    LL sum_x;
} tr[MAX_NODES];

int bin[MAX_NODES], bin_top;
int tot;

int new_node() {
    int u = bin_top ? bin[bin_top--] : ++tot;
    tr[u].ch[0] = tr[u].ch[1] = 0;
    tr[u].sz = 0;
    tr[u].sum_x = 0;
    tr[u].add_x = 0;
    tr[u].set_x = -1;
    return u;
}

void recycle(int u) {
    if (u) bin[++bin_top] = u;
}

void apply_set(int u, int val) {
    if (!u) return;
    tr[u].set_x = val;
    tr[u].add_x = 0;
    tr[u].sum_x = (LL)tr[u].sz * val;
}

void apply_add(int u, int val) {
    if (!u) return;
    if (tr[u].set_x != -1) {
        tr[u].set_x += val;
    } else {
        tr[u].add_x += val;
    }
    tr[u].sum_x += (LL)tr[u].sz * val;
}

void pushdown(int u) {
    if (tr[u].set_x != -1) {
        apply_set(tr[u].ch[0], tr[u].set_x);
        apply_set(tr[u].ch[1], tr[u].set_x);
        tr[u].set_x = -1;
    }
    if (tr[u].add_x != 0) {
        apply_add(tr[u].ch[0], tr[u].add_x);
        apply_add(tr[u].ch[1], tr[u].add_x);
        tr[u].add_x = 0;
    }
}

void pushup(int u) {
    tr[u].sz = 0;
    tr[u].sum_x = 0;
    if (tr[u].ch[0]) {
        tr[u].sz += tr[tr[u].ch[0]].sz;
        tr[u].sum_x += tr[tr[u].ch[0]].sum_x;
    }
    if (tr[u].ch[1]) {
        tr[u].sz += tr[tr[u].ch[1]].sz;
        tr[u].sum_x += tr[tr[u].ch[1]].sum_x;
    }
}

void insert(int &u, int val, int bit, int x_val) {
    if (!u) u = new_node();
    if (bit < 0) {
        tr[u].sz++;
        tr[u].sum_x += x_val;
        return;
    }
    pushdown(u);
    int b = (val >> bit) & 1;
    insert(tr[u].ch[b], val, bit - 1, x_val);
    pushup(u);
}


void split(int u, int &u_lt, int &u_ge, int v, int tag, int bit) {
    if (!u) { u_lt = u_ge = 0; return; }
    if (bit < 0) { u_lt = 0; u_ge = u; return; }
    pushdown(u);
    int b_v = (v >> bit) & 1;
    int b_tag = (tag >> bit) & 1;
    int act0 = b_tag;
    if (b_v == 1) {
        u_lt = u;
        u_ge = new_node();
        int dir_0 = (act0 == 0) ? 0 : 1;
        int dir_1 = 1 ^ dir_0;
        int ch_lt = 0, ch_ge = 0;
        split(tr[u].ch[dir_1], ch_lt, ch_ge, v, tag, bit - 1);
        tr[u_lt].ch[dir_1] = ch_lt;
        tr[u_ge].ch[dir_1] = ch_ge;
        tr[u_ge].ch[dir_0] = 0; 
        pushup(u_lt);
        pushup(u_ge);
        if (tr[u_lt].sz == 0) { recycle(u_lt); u_lt = 0; }
        if (tr[u_ge].sz == 0) { recycle(u_ge); u_ge = 0; }
    } else {
        u_lt = new_node();
        u_ge = u;
        int dir_0 = (act0 == 0) ? 0 : 1;
        int dir_1 = 1 ^ dir_0;
        int ch_lt = 0, ch_ge = 0;
        split(tr[u].ch[dir_0], ch_lt, ch_ge, v, tag, bit - 1);
        tr[u_ge].ch[dir_0] = ch_ge;
        tr[u_lt].ch[dir_0] = ch_lt;
        tr[u_lt].ch[dir_1] = 0;
        pushup(u_lt);
        pushup(u_ge);
        if (tr[u_lt].sz == 0) { recycle(u_lt); u_lt = 0; }
        if (tr[u_ge].sz == 0) { recycle(u_ge); u_ge = 0; }
    }
}

int merge(int u, int v, int bit) {
    if (!u || !v) return u | v;
    if (bit < 0) {
        tr[u].sz += tr[v].sz;
        tr[u].sum_x += tr[v].sum_x;
        recycle(v);
        return u;
    }
    pushdown(u); pushdown(v);
    tr[u].ch[0] = merge(tr[u].ch[0], tr[v].ch[0], bit - 1);
    tr[u].ch[1] = merge(tr[u].ch[1], tr[v].ch[1], bit - 1);
    pushup(u);
    recycle(v); 
    if (tr[u].sz == 0) { recycle(u); return 0; }
    return u;
}

cint N=1.02e5;
int n;
int a[N];

void main_solve()
{
    inint(n);
    for(int i = 1; i <= n; i++) inint(a[i]);
    tot = 0;
    bin_top = 0;
    int Trie[2] = {0, 0};
    int TAG = 0;
    LL ans = 0ll;
    for(int i = n; i >= 1; i--) {
        insert(Trie[1], TAG, MAX_BIT, 0);
        int T0_lt = 0, T0_ge = 0;
        split(Trie[0], T0_lt, T0_ge, a[i], TAG, MAX_BIT);
        int T1_lt = 0, T1_ge = 0;
        split(Trie[1], T1_lt, T1_ge, a[i], TAG, MAX_BIT);
        apply_set(T0_lt, 1);
        apply_set(T1_lt, 1);
        apply_add(T0_ge, 1);
        if (a[i] == 1) apply_add(T1_ge, 1);
        else apply_add(T1_ge, 2);
        int new_T0 = 0, new_T1 = 0;
        if (a[i] == 1) new_T0 = T1_ge;
        else new_T0 = 0;
        new_T1 = T0_lt;
        new_T1 = merge(new_T1, T1_lt, MAX_BIT);
        new_T1 = merge(new_T1, T0_ge, MAX_BIT);
        if (a[i] != 1) new_T1 = merge(new_T1, T1_ge, MAX_BIT);
        Trie[0] = new_T0;
        Trie[1] = new_T1;
        ans += (Trie[0] ? tr[Trie[0]].sum_x : 0) + (Trie[1] ? tr[Trie[1]].sum_x : 0);
        TAG ^= a[i];
    }
    outll(ans);
}

int main()
{
    main_init();
    main_solve();
    return 0;
}
0