Codeforces 845G 線性基模板

題意:問你找到一種方案使得從1走到N上邊權異或和最小。

解:先隨便找到一條,1到n的異或總和,然後將圖上所有換的異或和放入一個集合中秋線性基。

再把1到n的異或和在那個集合裏求最小能異或出來多少。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn =2e5+10;
const int maxm=maxn *2;
ll rd() {ll t;scanf("%I64d",&t);return t;}
#define en '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
const int mo=1e9;
struct L_B{
    long long d[65],p[65];
    int cnt;
    L_B()
    {
        memset(d,0,sizeof(d));
        memset(p,0,sizeof(p));
        cnt=0;
    }
    bool insert(long long val)
    {
        for (int i=62;i>=0;i--)
            if (val&(1LL<<i))
            {
                if (!d[i])
                {
                    d[i]=val;
                    break;
                }
                val^=d[i];
            }
        return val>0;
    }
    long long query_max()
    {
        long long ret=0;
        for (int i=62;i>=0;i--)
            if ((ret^d[i])>ret)
                ret^=d[i];
        return ret;
    }
    long long query_min()
    {
        for (int i=0;i<=62;i++)
            if (d[i])
                return d[i];
        return 0;
    }
    void rebuild()
    {
        for (int i=62;i>=0;i--)
            for (int j=i-1;j>=0;j--)
                if (d[i]&(1LL<<j))
                    d[i]^=d[j];
        for (int i=0;i<=62;i++)
            if (d[i])
                p[cnt++]=d[i];
    }
    long long kthquery(long long k)
    {
        int ret=0;
        if (k>=(1LL<<cnt))
            return -1;
        for (int i=62;i>=0;i--)
            if (k&(1LL<<i))
                ret^=p[i];
        return ret;
    }
    bool cunzai(ll x){
        for(int i=62;i>=0;--i){
            if((x>>i)&1){
                x=x^d[i];
            }
            if(x==0)return 1;
        }
        return 0;
    }
    ll querymin(ll x){
        for(int i=62;i>=0;--i){
            if((x>>i)&1 and d[i]){
                x^=d[i];
            }
        }
        return x;
    }
};
L_B lb;
struct node{
int v,nxt,w;
}edge[maxm];
int tot=1,head[maxn];
void add(int x,int y,int w){
edge[++tot]=(node){y,head[x],w};head[x]=tot;
}
bool vis[maxn];
int a[maxn];
void dfs(int x,int from,int res){
    a[x]=res;vis[x]=1;
    for(int i=head[x];i;i=edge[i].nxt){
        if((i^1)==from)continue;
        int y=edge[i].v;
        if(vis[y]){
            lb.insert(res^edge[i].w^a[y]);
        }
        else dfs(y,i,res^edge[i].w);
    }
}
signed main() {
#ifdef local
    freopen("input2.txt","r",stdin);
#endif // local
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int x=rd(),y=rd(),w=rd();
        add(x,y,w),add(y,x,w);
    }
    dfs(1,0,0);
    cout<<lb.querymin(a[n])<<en;
        return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章