### codeforces 703D Mishka and Interesting sum (树状数组区间异或)

#### 题意

``给出一个有n个元素的数组a[...], 1 <= a[i] <= 10^9,(n,m <= 10^6)。m次讯问区间[l,r]见出现了偶次的数的异或值。``

#### 思路

``可以先求出1到i的异或值sum[i] = sum[i - 1] ^ a[i];树状数组部分有点同于求区间数的种数。last记录每个数前一次出现的位置。走到i时，如果a[i]出现过，那么把他上次出现的位置异或掉，再在i位置上异或上a[i]。然后对所有以i结尾的讯问区间进行操作，这里就是异或计算了。``

``const int maxn = 1e6 + 100;struct BIT {    int a[maxn];    int n;    void init(int n) {        this->n = n;        memset(a, 0, sizeof a);    }    void add(int i, int val) {        for (;i <= n;i += lowbit(i))            a[i] ^= val;    }    int sum(int i) {        int res = 0;        for (;i > 0;i -= lowbit(i))            res ^= a[i];        return res;    }}solve;int a[maxn];map<int, int> last;vector<ii> vec[maxn];int sum[maxn];int ans[maxn];int main(int argc, const char * argv[]){        // freopen("in.txt","r",stdin);    // freopen("out.txt","w",stdout);    int n;cin >> n;    for (int i = 1;i <= n;++i) {        scanf("%d",&a[i]);        sum[i] = sum[i - 1] ^ a[i];    }    int q;cin >> q;    for (int i = 1;i <= q;++i) {        int l, r;        scanf("%d%d", &l, &r);        vec[r].push_back(ii(l, i));    }    int cnt = 0;    solve.init(n);    for (int i = 1;i <= n;++i) {        if (last.count(a[i])) solve.add(last[a[i]], a[i]);        solve.add(i, a[i]);        last[a[i]] = i;        for (auto& p : vec[i]) {            int res = sum[i] ^ sum[p.first - 1];            res ^= (solve.sum(i) ^ solve.sum(p.first - 1));            ans[p.second] = res;            cnt++;        }        if (cnt == q) break;    }    for (int i = 1;i <= q;++i)        printf("%d\n", ans[i]);    // showtime;    return 0;}``