• 给定一个无向简单图(即无重边无自环),每条边都有一个权值。

    这个图的一个割,指的是将它的点集划分为两个不重不漏的集合 (S)(T)

    这个割的权值,是所有两个端点分别属于 (S)(T) 的边的权值的异或和(即 (S) 内部的边和 (T) 内部的边都不算)。

    现在问这个图的 割的所有可能的权值 的和是多少。

    由于这个数很大,只需要输出 (9) 位,不足 (9) 位则全部输出。

    输入格式

    第一行两个数 (n)(m) 表示图的点数和边数。
    之后 (m) 行每行 (3) 个数 (x, y, z) 表示一条边的两个端点和这条边的权值。点的编号从 (1)(n)

    输出格式

    一行一个整数表示答案。

    数据范围

    (1le nle 10^5,1le mle min(frac{n(n-1)}{2},2 imes 10^5),0le zle 10^9)


    考场上看成对所有划分数求和了,那个真是没法做...

    考虑所有点都是白色,然后选择一个点染黑,会选择与这个点相连的所有边

    选择任意个不相邻的点染黑,会选择与这些点相连的边

    选择一对相邻的点染黑,那么某条边就不会被选了,可以被刚好异或掉

    因此,设定点权为与它相连的边权的异或和,对点求线性基就可以了

    然后在最后统计答案的时,所有满秩的位置显然可以选 0/1 ,那么其余满秩位置随便选的。

    但是不满秩的位置可能是 0 或者 1,我们一样需要统计非满秩位置的 1,不过当你选择这个非满秩的 1 时,实际上也钦定了某个满秩的位置是 1,所以一样的统计就可以了


    Code:

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define ll long long
    using std::min;
    const int SIZE=1<<21;
    char ibuf[SIZE],*iS,*iT;
    //#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
    #define gc() getchar()
    template <class T>
    void read(T &x)
    {
        x=0;int f=0;char c=gc();
        while(!isdigit(c)) f|=c=='-',c=gc();
        while(isdigit(c)) x=x*10+c-'0',c=gc();
        if(f) x=-x;
    }
    const int N=1e5+10;
    int n,m,yuu[N],aya[30],cnt,base[40];
    ll ans;
    void ins(int x)
    {
        for(int i=30;~i;i--)
            if(x>>i&1)
            {
                if(base[i]) x^=base[i];
                else
                {
                    base[i]=x;
                    return;
                }
            }
    }
    int main()
    {
        read(n),read(m);
        for(int u,v,z,i=1;i<=m;i++)
        {
            read(u),read(v),read(z);
            yuu[u]^=z,yuu[v]^=z;
        }
        for(int i=1;i<=n;i++) ins(yuu[i]);
        for(int i=0;i<=30;i++) cnt+=base[i]>0;
        for(int i=0;i<=30;i++)
        {
            int flag=0;
            for(int j=0;j<30;j++) flag|=base[j]>>i&1;
            if(flag)
                ans+=(1ll<<cnt-1)*(1ll<<i);
        }
        while(ans) aya[++aya[0]]=ans%10,ans/=10;
        for(int i=1;i<=min(aya[0],9);i++)
            printf("%d",aya[aya[0]-i+1]);
        return 0;
    }
    

    2019.6.14

  • 相关阅读:
    quartz 之misfire
    quartz 之job
    quartz 日志观察
    quartz集群原理2
    netty 之 GlobalEventExecutor
    redis 修改配置文件不起作用?
    Qto_MemberBaseQuantities
    Qto_PlateBaseQuantities
    Pset_BuildingElementProxyCommon
    matlab绘制函数(观察凹凸性)
  • 原文地址:https://www.cnblogs.com/butterflydew/p/11022082.html
Copyright © 2020-2023  润新知