• bzoj4568(合并线性基+倍增)


    裸题练习模板

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    #include<vector> 
    using namespace std;
    typedef long long ll;
    const int maxn=40010;
    vector<ll>v[maxn][16];
    int d[maxn],n,Q,fa[maxn][16],last[maxn],pre[maxn],other[maxn],t;
    void add(int x,int y){++t;pre[t]=last[x];last[x]=t;other[t]=y;}
    ll x,q[maxn];
    vector<ll> uni(vector<ll> a,vector<ll> b){
        vector<ll>ans;
        int top=0,lena=a.size(),lenb=b.size();
        for(int i=0;i<lena;++i)q[++top]=a[i];
        for(int i=0;i<lenb;++i)q[++top]=b[i];
        int p=0;
        for(int j=60;j>=0;--j){
            bool flag=0;
            for(int i=p+1;i<=top;++i)
            if((q[i]>>j)&1){
                swap(q[i],q[++p]);
                flag=1;break;
            }
            if(!flag)continue;
            for(int i=1;i<=top;++i)
            if(i!=p){
                if((q[i]>>j)&1)q[i]^=q[p];
            }
        }
        for(int i=1;i<=p;++i)ans.push_back(q[i]);
        return ans;
    }
    void dfs(int x){
        for(int i=last[x];i;i=pre[i]){
            int v=other[i];
            if(v==fa[x][0])continue;
            d[v]=d[x]+1;fa[v][0]=x;
            dfs(v);
        }
    }
    int lca(int x,int y){
        if(d[x]<d[y])swap(x,y);
        for(int i=15;i>=0;--i)
        if(d[fa[x][i]]>=d[y])x=fa[x][i];
        if(x==y)return x;
        for(int i=15;i>=0;--i)
        if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
        return fa[x][0];
    }
    int jump(int x,int y){
        for(int i=15;i>=0;--i){
            if((1<<i)&y)x=fa[x][i];
        }
        return x;
    }
    vector<ll> qs(int x,int y){
        int k=log2(d[x]-d[y]+1);
        return uni(v[x][k],v[jump(x,d[x]-d[y]+1-(1<<k))][k]);
    }
    int main(){
        cin>>n>>Q;
        for(int i=1;i<=n;++i){
            scanf("%lld",&x);
            v[i][0].push_back(x);
        }
        int a,b,tmp;
        for(int i=1;i<n;++i){
            scanf("%d%d",&a,&b);
            add(a,b);add(b,a);
        }
        dfs(1);
        for(int j=1;j<=15;++j)
        for(int i=1;i<=n;++i){
            fa[i][j]=fa[fa[i][j-1]][j-1];
            v[i][j]=uni(v[i][j-1],v[fa[i][j-1]][j-1]);
        }
        while(Q--){
            scanf("%d%d",&a,&b);
            tmp=lca(a,b);
            vector<ll>ans=uni(qs(a,tmp),qs(b,tmp));
            ll res=0,siz=ans.size();
            for(int i=0;i<siz;++i)
            if((res^ans[i])>res)res^=ans[i];
            printf("%lld
    ",res);
        }
        return 0;
    } 
  • 相关阅读:
    MyEclipse 修改代码不生效
    最简单的网页分享代码
    php libevent 扩展使用示例
    function gzdecode
    20165327 2017-2018-2 《Java程序设计》第9周学习总结
    结对编程_四则运算
    20165327 2017-2018-2 《Java程序设计》第8周学习总结
    2017-2018-2 20165327 实验二 《Java面向对象程序设计》实验报告
    20165327 2017-2018-2 《Java程序设计》第7周学习总结
    20165327 2017-2018-2 《Java程序设计》第6周学习总结
  • 原文地址:https://www.cnblogs.com/dibaotianxing/p/8695952.html
Copyright © 2020-2023  润新知