BZOJ2115: [Wc2011] Xor
题解:
n个元素的子集的最大异或和我居然理解了一星期 T_T lyd讲解坑死人。。。
http://sujinyue.is-programmer.com/posts/42663.html
这里解决了我的所有疑问。
所谓线性基就是原数组所能xor出的一切数这个线性基都能xor出来,不多不少。为什么可以呢?我们可以对于每一个线性基的选择按构造方案逆回去就找到了原数组的选择方案。
其实就是对于每一位保留了一个前面都是0,该位是1的数,后面随意。
而任何一个数与该数组异或最大或最小,我们只需要贪心的考虑每一位即可。
最大就从高位往低位选,最小就从低位往高位选。
具体关于此题的解法就不说了,网上一大堆。eg:http://wenku.baidu.com/view/fbb1e3e8aeaad1f346933f6d.html
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 100000+5 14 #define maxm 1000000+5 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 23 #define mod 1000000007 24 using namespace std; 25 inline ll read() 26 { 27 ll x=0,f=1;char ch=getchar(); 28 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 29 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 30 return x*f; 31 } 32 struct edge{int go,next;ll w;}e[maxm]; 33 ll a[maxn<<1],b[maxn],ans,d[maxn]; 34 int n,m,k,tot,head[maxn]; 35 bool v[maxn]; 36 inline void add(int x,int y,ll w) 37 { 38 e[++tot]=(edge){y,head[x],w};head[x]=tot; 39 e[++tot]=(edge){x,head[y],w};head[y]=tot; 40 } 41 inline void dfs(int x) 42 { 43 v[x]=1; 44 for4(i,x)if(!v[y]) 45 { 46 d[y]=d[x]^e[i].w; 47 dfs(y); 48 }else a[++k]=d[x]^d[y]^e[i].w; 49 } 50 int main() 51 { 52 freopen("input.txt","r",stdin); 53 freopen("output.txt","w",stdout); 54 n=read();m=read(); 55 for1(i,m){int x=read(),y=read();add(x,y,read());} 56 dfs(1); 57 ans=d[n]; 58 for1(i,k) 59 for3(j,63,0) 60 if(a[i]>>j&1) 61 { 62 if(!b[j]){b[j]=a[i];break;} 63 else a[i]^=b[j]; 64 } 65 for3(i,63,0)ans=max(ans,ans^b[i]); 66 cout<<ans<<endl; 67 return 0; 68 }