1. 程式人生 > >Lyft Level 5 Challenge 2018

Lyft Level 5 Challenge 2018

F. Deduction Queries
time limit per test 2 seconds
memory limit per test 256 megabytes
inputstandard input
outputstandard output

There is an array a of 2302^{30} integers, indexed from 0 to 23012^{30}−1. Initially, you know that 0ai<230(0i<230)0≤a_i<2^{30} (0≤i<2^{30})

230(0i<230), but you do not know any of the values. Your task is to process queries of two types:

1 l r x: You are informed that the bitwise xor of the subarray [l,r] (ends inclusive) is equal to x. That is,alal+1ar1ar=xa_l⊕a_{l+1}⊕…⊕a_{r−1}⊕a_r=x, where ⊕ is the bitwise xor operator. In some cases, the received update contradicts past updates. In this case, you should ignore the contradicting update (the current update).
2 l r: You are asked to output the bitwise xor of the subarray [l,r] (ends inclusive). If it is still impossible to know this value, considering all past updates, then output −1.
Note that the queries are encoded. That is, you need to write an online solution.

Input
The first line contains a single integer q(1q2105)q (1≤q≤2⋅10^5) — the number of queries.

Each of the next q lines describes a query. It contains one integer t(1t2)t (1≤t≤2) — the type of query.

The given queries will be encoded in the following way: let last be the answer to the last query of the second type that you have answered (initially, last=0). If the last answer was −1, set last=1.

If t=1, three integers follow, ll^′, rr^′, and xx^′ (0l,r,x&lt;230)(0≤l^′,r^′,x^′&lt;2^{30}), meaning that you got an update. First, do the following:
l=llast,r=rlast,x=xlastl=l^′⊕last, r=r^′⊕last, x=x^′⊕last
and, if l&gt;rl&gt;r, swap l and r.

This means you got an update that the bitwise xor of the subarray [l,r] is equal to x (notice that you need to ignore updates that contradict previous updates).

If t=2, two integers follow, ll^′ and rr^′ (0l,r&lt;230)(0≤l^′,r^′&lt;2^{30}), meaning that you got a query. First, do the following:
l=llast,r=rlastl=l^′⊕last, r=r^′⊕last
and, if l&gt;rl&gt;r, swap l and r.

For the given query, you need to print the bitwise xor of the subarray [l,r]. If it is impossible to know, print −1. Don’t forget to change the value of last.

It is guaranteed there will be at least one query of the second type.

Output
After every query of the second type, output the bitwise xor of the given subarray or −1 if it is still impossible to know.

Examples
input
12
2 1 2
2 1 1073741822
1 0 3 4
2 0 0
2 3 3
2 0 3
1 6 7 3
2 4 4
1 0 2 1
2 0 0
2 4 4
2 0 0
output
-1
-1
-1
-1
5
-1
6
3
5
input
4
1 5 5 9
1 6 6 5
1 6 5 10
2 6 5
output
12

思路:帶權並查集,原題:https://www.nowcoder.com/acm/contest/119/A。
這題只是把資料範圍加大了,因為並查集其實和大小沒有關聯,所以可以把區間離散化。
r[i]r[i]表示區間(p[i],i](p[i],i]裡所有數的異或值。

#include<bits/stdc++.h>
using namespace std;
const int MAX=4e5+10;
map<int,int>ma;
int p[MAX],r[MAX];
int f(int x)
{
    if(p[x]==x)return x;
    int nex=p[x];
    p[x]=f(p[x]);
    r[x]^=r[nex];
    return p[x];
}
int main()
{
    for(int i=1;i<=4e5;i++)p[i]=i,r[i]=0;
    int T,last=0,cnt=1;
    cin>>T;
    while(T--)
    {
        int op,x,y,z;
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d%d",&x,&y,&z);
            x^=last;
            y^=last;
            z^=last;
            if(x>y)swap(x,y);
            x--;        //因為是[x,y]的異或值為z,所以在並查集裡面查詢合併之前,x--
            if(ma[x]==0)ma[x]=cnt++;
            if(ma[y]==0)ma[y]=cnt++;
            x=ma[x];
            y=ma[y];
            int fx=f(x),fy=f(y);
            if(fx==fy)continue;
            p[fy]=fx;
            r[fy]=r[y]^r[x]^z;
        }
        else
        {
            scanf("%d%d",&x,&y);
            x^=last;
            y^=last;
            if(x>y)swap(x,y);
            x--;
            if(ma[x]==0)ma[x]=cnt++;
            if(ma[y]==0)ma[y]=cnt++;
            x=ma[x];
            y=ma[y];
            int fx=f(x),fy=f(y);
            if(fx==fy)last=r[x]^r[y];
            else last=-1;
            printf("%d\n",last);
        }
        if(last==-1)last=1;
    }
	return 0;
}