• codeforces 724G


    题目传送门

    题意:给出衣服无向带权图,问有多少对合法的$<u,v,s>$,要求$u$到$v$存在一条路径(不一定是简单路径)权值异或和等于$s$,并且$u<v$。求所有合法三元组的s的和。

    思路:

      参考了一篇大佬的博客。

      这类题的核心思想就是,两点之间的所有可能的路径,都是由一条简单路径加上若干个环组成的。u,v两点所有路径的异或值的集合,等价于,u,v一条简单路径的异或值,与整个连通图的所有环组成的线性基异或的集合。

      所以按位考虑每个二进制1给整幅图带来的价值。

      特别要注意的一点是,在处理线性基的过程中,最多处理到63位,如果处理到64位及以上,当$i>=64$,某些$(x>>i)$,或者$(x<<i)$,就会发出许多诡异的错误,wa了很久。

    #pragma GCC optimize (2)
    #pragma G++ optimize (2)
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<bits/stdc++.h>
    #include<cstdio>
    #include<vector>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define dep(i,b,a) for(int i=b;i>=a;i--)
    #define clr(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    #define pii pair<int,int >
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    ll rd()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int maxn=100010;
    const ll mod=1e9+7;
    int n,m;
    struct edge{
        int to;
        ll w;
    };
    vector<edge >ve[maxn];
    int vis[maxn];
    ll del[maxn],p[70],siz,num[70],ans=0,tot=0;
    void init(){
        rep(i,1,n){
            ve[i].clear();
            vis[i]=0;
        }
        ans=0,siz=0,clr(p,0);
    }
    bool insert(ll x){
        dep(i,63,0){
            if((x>>i)&1){
                if(!p[i]){
                    p[i]=x;
                    return true;
                }
                x^=p[i];
            }
        }
        return false;
    }
    void dfs(int u,ll res){
        del[u]=res;
        for(ll i=63;i>=0;i--){
            if(((res>>i)&1)){
                num[i]++;
            }
        }
        tot++;
        vis[u]=1;
        for(auto &st:ve[u]){
            if(!vis[st.to]){
                dfs(st.to,res^st.w);
            }else{
                if(insert(res^st.w^del[st.to])){
                    siz++;
                }
            }
        }
    }
    int main(){
        while(cin>>n>>m){
            init();
            rep(i,1,m){
                int u,v;
                ll w;
                u=rd(),v=rd(),w=rd();
                ve[u].pb({v,w});
                ve[v].pb({u,w});
            }
            rep(u,1,n){
                if(!vis[u]){
                    tot=0;
                    clr(p,0),siz=0;
                    clr(num,0);
                    dfs(u,0);
                    dep(i,63,0){
                        bool ok=0;
                        dep(j,63,0){
                            if((p[j]>>i)&1)ok=1;
                        }
                        if(ok){
                            ans=(ans+tot*(tot-1)/2%mod*((1ll<<(siz-1))%mod)%mod*((1ll<<i)%mod)%mod)%mod;
                        }else{
                            ans=(ans+num[i]*(tot-num[i])%mod*((1ll<<siz)%mod)%mod*((1ll<<i)%mod)%mod)%mod;
                        }
                    }
                }
            }
            printf("%lld
    ",ans);
        }
    }
    
     
  • 相关阅读:
    Java RunTime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. ......
    UVA 1597 Searching the Web
    UVA 1596 Bug Hunt
    UVA 230 Borrowers
    UVA 221 Urban Elevations
    UVA 814 The Letter Carrier's Rounds
    UVA 207 PGA Tour Prize Money
    UVA 1592 Database
    UVA 540 Team Queue
    UVA 12096 The SetStack Computer
  • 原文地址:https://www.cnblogs.com/mountaink/p/11635215.html
Copyright © 2020-2023  润新知