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.

扫描二维码关注公众号,回复: 5102660 查看本文章

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
今日推荐