• 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);
        }
    }
    
     
  • 相关阅读:
    极光推送的设备唯一性标识 RegistrationID
    排行榜算法设计实现比较 排序树 平衡二叉树
    UCloud首尔机房整体热迁移是这样炼成的
    from appium import webdriver 使用python爬虫,批量爬取抖音app视频(requests+Fiddler+appium)
    客户续费模型 逻辑回归 分类器 AdaBoost
    推举算法 AdaBoost 哥德尔奖 Godel Prize
    基于 redis 的分布式锁实现 Distributed locks with Redis debug 排查错误
    Django’s cache framework
    随机森林算法预测法官判决
    时间特征正弦化
  • 原文地址:https://www.cnblogs.com/mountaink/p/11635215.html
Copyright © 2020-2023  润新知