zoukankan      html  css  js  c++  java
  • 【YBTOJ】【Luogu P4570】[BJWC2011]元素

    链接:

    洛谷

    博客园

    题目大意:

    (n) 个物品,第 (i) 个物品有一个权值和一个序号。你需要在这之中选若干个物品,使得其中任意一个物品序号不会被其他数表示。求出一个权值最大的可行方案。

    正文:

    可以贪心权值从大到小选择当前物品是否可行。

    如何证明这个的正确性呢?假设有三个物品 (i,j,k),其中 (i,j) 在线性基中,而 (k) 不在(即 (val_k<val_i,val_j)),且 (id_i ext{xor}id_j=id_k)。可以很容易发现如果让 (k) 插入线性基放弃 (i)(j) 的话肯定不是最优的。

    然后就是利用线性基能够判断当前数能否被线性基里的数异或表示的性质解题了。假设我们插入 (k) 失败,它会因为在线性基里不断异或里面的数而最后变成 (0),那统计答案时只需要看最后的 (id_k) 是否为零就好了。

    代码:

    struct node
    {
    	ll val, id;
    	bool operator < (const node &x) const
    	{
    		return val > x.val;
    	}
    }a[N];
    
    int n; 
    ll ans;
    ll d[65];
    void Insert(ll &val)
    {
    	for(int i = 64; i >= 0; --i)
    		if(val & (1ll << i))
    		{
    			if (d[i]) val ^= d[i];
    			else {d[i] = val; return;} 
    		}
    }
    
    int main()
    {
    //	freopen(".in", "r", stdin);
    //	freopen(".out", "w", stdout);
    	scanf ("%d", &n);
    	for (int i = 1; i <= n; i++)
    		scanf ("%lld%lld", &a[i].id, &a[i].val);
    	sort (a + 1, a + 1 + n);
    	
    	for (int i = 1; i <= n; i++)
    	{
    		Insert(a[i].id);
    		if (a[i].id) ans += a[i].val;
    	}
    	printf ("%lld
    ", ans);
        return 0;
    }
    
    
  • 相关阅读:
    Jenkins动态部署方案
    01-Java学习笔记
    Tcp实现简单的大小写转换功能
    JavaScript 执行环境 与 变量对象
    JQuery
    JavaScript模板引擎
    ECMA6
    谷歌控制台
    prototype 与 __proto__
    JavaScript Math
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/14453999.html
Copyright © 2011-2022 走看看