Lyft Level 5 Challenge 2018 - Final Round:F. Deduction Queries(带权并查集)

版权声明:http://blog.csdn.net/Mitsuha_。 https://blog.csdn.net/Mitsuha_/article/details/83895007

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 2 30 2^{30} integers, indexed from 0 to 2 30 1 2^{30}−1 . Initially, you know that 0 a i < 2 30 ( 0 i < 2 30 ) 0≤a_i<2^{30} (0≤i<2^{30}) , 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, a l a l + 1 a r 1 a r = x a_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 ( 1 q 2 1 0 5 ) q (1≤q≤2⋅10^5) — the number of queries.

Each of the next q lines describes a query. It contains one integer t ( 1 t 2 ) 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, l l^′ , r r^′ , and x x^′ ( 0 l , r , x < 2 30 ) (0≤l^′,r^′,x^′<2^{30}) , meaning that you got an update. First, do the following:
l = l l a s t , r = r l a s t , x = x l a s t l=l^′⊕last, r=r^′⊕last, x=x^′⊕last
and, if l > r l>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, l l^′ and r r^′ ( 0 l , r < 2 30 ) (0≤l^′,r^′<2^{30}) , meaning that you got a query. First, do the following:
l = l l a s t , r = r l a s t l=l^′⊕last, r=r^′⊕last
and, if l > r l>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;
}


猜你喜欢

转载自blog.csdn.net/Mitsuha_/article/details/83895007