Loading [MathJax]/jax/output/CommonHTML/jax.js
Solutions of XORray - MarisaOJ: Marisa Online Judge

Solutions of XORray

Select solution language

Write solution here.


User Avatar nxhhoang    Created at    5 likes

Ý tưởng

  • Ta quy ước là phép XOR, + là phép OR. là phép AND.
  • Xét n phần tử A1,A2,A3,,An.
  • Ta lập bảng như sau, với các tổng OR ở cột phần tử Ai bắt đầu lần lượt từ 1,2,,i1,i và kết thúc tại i. Đây cũng chính là số tổng cần có để tính tổng XOR.
Phần tử A1 Phần tử A2 Phần tử A3 Phần tử An
f(1,1) f(1,2) f(1,3) f(1,n)
f(2,2) f(2,3) f(2,n)
f(3,3) f(3,n)
f(n,n)
_____________ _____________ _____________ ___ ____________
F(1,1) F(1,2) F(1,3) F(1,n)
  • Ta định nghĩa F(1,k) là tổng XOR của các tổng OR kết thúc tại k.

  • Vậy yêu cầu của bài toán trở thành: Tính tổng XOR của các tổng F(1,k) với k1,2,,n.

  • Ta có: F(1,1)=f(1,1)=A1.

  • Tiếp tục: F(1,2)=f(1,2)f(2,2)=(A1+A2)(A2)=A1.¯A2.

  • Tiếp tục: F(1,3)=f(1,3)f(2,3)f(3,3)=(A1+A2+A3)(A2+A3)(A3)=A1.¯A2+A3.

  • Tiếp tục: F(1,4)=(A1.¯A2+A3).¯A4.

  • Bằng phép quy nạp dễ dàng xây dựng được công thức truy hồi như sau: F(1,n)={A1,if n==1F(1,n1)+An,if n is oddF(1,n1).¯An,if n is even

Code C++

// nxxhoang - the dreamer
#include <bits/stdc++.h>
#define FOR(i, a, b) for (int i = a; i < (int)b; i++)
#define endl '\n'

using namespace std;
using ll = long long;
using ull = unsigned long long;

void solve(){
    int n, a, result = 0, cur = 0;
    cin >> n;
    FOR (i, 1, n + 1) {
        cin >> a;
        if (i % 2) cur |= a;
        else cur &= ~a;
        result ^= cur;
    }
    cout << result;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    solve();
    return 0;
}