1. 程式人生 > 實用技巧 >習題:Deduction Queries(冰茶姬)

習題:Deduction Queries(冰茶姬)

題目

傳送門

思路

考慮到異或的特殊性

將區間轉換成兩個字首異或和的異或即可

程式碼

#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
namespace ufs
{
    int fa[400005];
    int w[400005];
    void makeset(int n)
    {
        for(int i=1;i<=n;i++)
            fa[i]=i;
    }
    int findset(int x)
    {
        if(fa[x]==x)
            return x;
        int t=findset(fa[x]);
        w[x]^=w[fa[x]];
        return fa[x]=t;
    }
    void merge(int u,int v,int ty)
    {
        swap(u,v);
        int a=findset(u);
        int b=findset(v);
        fa[a]=b;
        w[a]=w[u]^ty^w[v];
        w[b]=0;
    }
}
using namespace ufs;
int n,cnt;
int lans;
int opt,l,r,x;
map<int,int> hashh;
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    makeset(2*n);
    for(int i=1;i<=n;i++)
    {
        cin>>opt>>l>>r;
        l^=lans;
        r^=lans;
        if(l>r)
        	swap(l,r);
        l--;
        if(hashh.count(l)==0)
            hashh[l]=++cnt;
        if(hashh.count(r)==0)
            hashh[r]=++cnt;
        l=hashh[l];
        r=hashh[r];
        if(opt==1)
        {
            cin>>x;
            x^=lans;
            if(findset(l)!=findset(r))
                merge(l,r,x);
        }
        else
        {
            if(findset(l)!=findset(r))
            {
                lans=1;
                cout<<"-1\n";
            }
            else
            {
                lans=w[l]^w[r];
                cout<<lans<<'\n';
            }
            
        }
        
    }
    return 0;
}