真正的危机不是机器人像人一样思考,而是人像机器一样思考。 ——凉宫春日的忧郁

[BeiJing2011]元素

[BeiJing2011]元素

题目

相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术。那时人们就认识到,一个法杖的法力取决于使用的矿石。一般地,矿石越多则法力越强,但物极必反:有时,人们为了获取更强的法力而使用了很多矿石,却在炼制过程中发现魔法矿石全部消失了,从而无法炼制出法杖,这个现象被称为“魔法抵消” 。特别地,如果在炼制过程中使用超过一块同一种矿石,那么一定会发生“魔法抵消”。 
后来,随着人们认知水平的提高,这个现象得到了很好的解释。经过了大量的实验后,著名法师 Dmitri 发现:如果给现在发现的每一种矿石进行合理的编号(编号为正整数,称为该矿石的元素序号),那么,一个矿石组合会产生“魔法抵消”当且仅当存在一个非空子集,那些矿石的元素序号按位异或起来为零。 (如果你不清楚什么是异或,请参见下一页的名词解释。 )例如,使用两个同样的矿石必将发生“魔法抵消”,因为这两种矿石的元素序号相同,异或起来为零。 
并且人们有了测定魔力的有效途径,已经知道了:合成出来的法杖的魔力等于每一种矿石的法力之和。人们已经测定了现今发现的所有矿石的法力值,并且通过实验推算出每一种矿石的元素序号。 
现在,给定你以上的矿石信息,请你来计算一下当时可以炼制出的法杖最多有多大的魔力。 

INPUT

第一行包含一个正整数N,表示矿石的种类数。 
接下来 N行,每行两个正整数Numberi 和 Magici,表示这种矿石的元素序号和魔力值。

OUTPUT

仅包一行,一个整数:最大的魔力值

SAMPLE

INPUT

3

1 10

2 20

3 30

OUTPUT

50

解题报告

线性基+贪心

按权值从大到小排序,扔到线性基里面贪心就好了

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 using namespace std;
 6 typedef long long L;
 7 inline L read(){
 8     L sum(0);
 9     char ch(getchar());
10     for(;ch<'0'||ch>'9';ch=getchar());
11     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
12     return sum;
13 }
14 int n;
15 struct stone{
16     L num,w;
17     inline bool operator<(const stone &x)const{
18         return w>x.w;
19     }
20 }a[1005];
21 L base[65];
22 L ans;
23 int main(){
24 //  freopen("data.txt","r",stdin);
25     n=read();
26     for(int i=1;i<=n;++i)
27         a[i].num=read(),a[i].w=read();
28     sort(a+1,a+n+1);
29     for(int i=1;i<=n;++i){
30         for(int j=63;j>=0;--j)
31             if(a[i].num&(1LL<<j)){
32                 if(!base[j]){
33                     base[j]=a[i].num;
34                     break;
35                 }
36                 else
37                     a[i].num^=base[j];
38             }
39         if(a[i].num)
40             ans+=a[i].w;
41     }
42     printf("%lld",ans);
43 }
View Code

 

posted @ 2017-10-11 16:03  Hzoi_Mafia  阅读(141)  评论(0编辑  收藏  举报
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。 ——死神