BZOJ 2115 [Wc2011] Xor [线性基]

标签: 线性基
28人阅读 评论(0) 收藏 举报
分类:

题意:给你n个点m条带权边的无向图,求1到n路径的最大权值异或和。

题解:我们可以简单的推论出,这条路径肯定是1到n的一条路径再加上几个环,假如我们想从当前节点i去取点j开始一个环,那我们可以有这样一条路径,i->j->环->j-i,对于这条路径,我们的异或贡献为这个环上的值,所以我们只需要找出这个图中的所有的环,形成一个线性基,然后任意取1到n的一条路径,从线性基的最大位开始贪心的取,就能找到答案了。对于寻找环,我们直接dfs,对于有重边的环我们虽然不能找到所有的情况(有重边的环),但是我们可以根据已有的几个环异或出其他环的贡献,例如:


假如我们dfs的顺序为1->2->3->1->4->1的话,我们只能找出1->2->3->1于1->2->3->4->1这两个环,但是我们可以通过异或操作计算出环1->3->4->1的贡献,也就是线性基的定义。

AC代码:

#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
struct edge
{
	ll to,next,w;
	edge(){}
	edge(ll to,ll next,ll w)
	{
		this->to=to;
		this->next=next;
		this->w=w;
	}
}ed[200005];
ll head[50005],lnum,a[50005];
void addline(ll u,ll v,ll w)
{
	ed[lnum]=edge(v,head[u],w);
	head[u]=lnum++;
}

struct L_B{
    ll d[61],p[61];
    ll cnt;
    L_B()
    {
        memset(d,0,sizeof(d));
        memset(p,0,sizeof(p));
        cnt=0;
    }
    bool insert(ll val)
    {
        for (ll i=60;i>=0;i--)
            if (val&(1LL<<i))
            {
                if (!d[i])
                {
                    d[i]=val;
                    break;
                }
                val^=d[i];
            }
        return val>0;
    }
    ll query_max()
    {
        ll ret=0;
        for (ll i=60;i>=0;i--)
            if ((ret^d[i])>ret)
                ret^=d[i];
        return ret;
    }
    ll query_min()
    {
        for (ll i=0;i<=60;i++)
            if (d[i])
                return d[i];
        return 0;
    }
    void rebuild()
    {
        for (ll i=60;i>=0;i--)
            for (ll j=i-1;j>=0;j--)
                if (d[i]&(1LL<<j))
                    d[i]^=d[j];
        for (ll i=0;i<=60;i++)
            if (d[i])
                p[cnt++]=d[i];
    }
    ll kthquery(ll k)
    {
        ll ret=0;
        if (k>=(1LL<<cnt))
            return -1;
        for (ll i=60;i>=0;i--)
            if (k&(1LL<<i))
                ret^=p[i];
        return ret;
    }
}q;
L_B merge(const L_B &n1,const L_B &n2)
{
    L_B ret=n1;
    for (ll i=60;i>=0;i--)
        if (n2.d[i])
            ret.insert(n2.d[i]);
    return ret;
}
void dfs(ll u,ll now)
{
	a[u]=now;
	for(ll i=head[u];~i;i=ed[i].next)
	{
		ll to=ed[i].to;
		if(a[to]==-1)dfs(to,now^ed[i].w);
		else q.insert(now^ed[i].w^a[to]);
	}
}
int main()
{
	memset(a,-1,sizeof(a));
	memset(head,-1,sizeof(head));
	ll n,m;
	scanf("%lld%lld",&n,&m);
	for(ll i=0;i<m;i++)
	{
		ll u,v,w;
		scanf("%lld%lld%lld",&u,&v,&w);
		addline(u,v,w);
		addline(v,u,w);
	}
	dfs(1,0);
	ll ans=a[n];
	for(ll i=60;i>=0;i--)
		if((ans^q.d[i])>ans)
			ans^=q.d[i];
	printf("%lld\n",ans);
} 


查看评论

【bzoj2115】[Wc2011] Xor 线性代数

好坑爹呀,现在都不知道自己退没退役,还不让回去学文化课,还要被带去省队集训被虐 …… 这个东西比较复杂呀!!! 首先是第一个问题,给定n个数,选出若干数与x的异或值最大为多少? 这个东西处理出线...
  • u012288458
  • u012288458
  • 2016-05-18 16:59:43
  • 609

【BZOJ2115】【Wc2011】 Xor 线性基 异或最长路

题意:找一条异或最长路。 题解:先随便来一条路径,然后我们发现这条路径上可以随便加简单环(不管有没有共点共边)、 就是因为可以先从某点走到环上来一圈再走回来,这样来去的路径被搞没了,简直污得不行。...
  • Vmurder
  • Vmurder
  • 2015-02-02 16:48:10
  • 1476

【BZOJ2115】Xor,第一次的线性基

梁哥,我们有你智障吗
  • xym_CSDN
  • xym_CSDN
  • 2016-08-26 21:11:55
  • 855

BZOJ 2115 WC2011 Xor 线性基+贪心

题目大意:给出一个无向图,求出1~N的最长xor路径。 思路:先求出一条任意的1~N的路径的xor和,之后算出所有的简单环中的异或和。注意到异或的一个很好的性质——x^y^x=y,也就是说对...
  • jiangyuze831
  • jiangyuze831
  • 2015-02-03 16:48:49
  • 828

bzoj 2115 [Wc2011] Xor - 线性基

发现答案就是从1到n的一条路径和某些环的异或,而环的以后等价于无向图dfs树的非树边。 #include&amp;lt;iostream&amp;gt; #include&amp;lt;cstr...
  • Mys_C_K
  • Mys_C_K
  • 2018-04-12 11:23:50
  • 30

[BZOJ 2115 Wc2011 Xor]线性基

[BZOJ 2115 Wc2011 Xor]线性基分类:Math bitmask 线性基 1. 题目链接[BZOJ 2115 Wc2011 Xor]2. 题意描述一个边权非负整数的无向连通图,节点编号...
  • ACMore_Xiong
  • ACMore_Xiong
  • 2017-12-08 18:58:03
  • 64

2115: [Wc2011] Xor

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 2568  Solved: 1086 [Submit][S...
  • CRZbulabula
  • CRZbulabula
  • 2016-10-15 23:42:00
  • 385

BZOJ 2115: [Wc2011] Xor 线性基

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 3439  Solved: 1457 [Submit][S...
  • BlackJack_
  • BlackJack_
  • 2017-08-03 22:08:30
  • 127

[BZOJ 2115][Wc2011] Xor:线性基

点击这里查看原题结论:答案一定是任意一条1~n的路径异或某些环得到的值 接下来是证明为什么每个环都可以取到:如果要取某个环,可以从1出发到这个环上,走一圈后原路回到1,这样就得到了这个环的异或值。 ...
  • SmallSXJ
  • SmallSXJ
  • 2017-06-13 16:03:45
  • 211

【BZOJ 2115】[Wc2011] Xor 线性基

环^链=链,所以找到一条从1到n的路径和很多很多环,这时候就可以任意异或了,异或和最大,然后用到线性基。 #include #include #include #define cmax(a,b) (...
  • pbihao
  • pbihao
  • 2016-12-19 15:37:30
  • 103
    个人资料
    持之以恒
    等级:
    访问量: 5万+
    积分: 2744
    排名: 1万+
    最新评论