zoukankan      html  css  js  c++  java
  • 【LOJ6060】【2017 山东一轮集训 Day1 / SDWC2018 Day1】Set 线性基

    题目大意

      给出 (n) 个非负整数,将数划分成两个集合,记为一号集合和二号集合。(x_1) 为一号集合中所有数的异或和,(x_2) 为二号集合中所有数的异或和。在最大化 (x_1 + x_2) 的前提下,最小化 (x_1)

      (nleq 100000,0leq a_ileq {10}^8)

    题解

      记 (s=a_1operatorname{xor} a_2operatorname{xor} a_3operatorname{xor} cdotsoperatorname{xor}a_n)

      那么就是要在最大化 (soperatorname{xor}x_2+x_2) 的前提下最大化 (x_2)

      如果对于一个二进制位 (i),如果 (s) 在这一位上的值为 (0),并且 (x_2) 在这一位上的值为 (1),那么就会对 (soperatorname{xor}x_2+x_2)(2^{i+1}) 的贡献。

      如果对于一个二进制位 (i),如果 (s) 在这一位上的值为 (1),并且 (x_2) 在这一位上的值为 (1),那么就会对 (x_2)(2^i) 的贡献。

      那么把这些二进制位分成两部分,求线性基,然后随便搞搞贪心取就好了。

      时间复杂度:(O(nlog V))

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<ctime>
    #include<utility>
    #include<functional>
    #include<cmath>
    //using namespace std;
    using std::min;
    using std::max;
    using std::swap;
    using std::sort;
    using std::reverse;
    using std::random_shuffle;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef std::pair<int,int> pii;
    typedef std::pair<ll,ll> pll;
    void open(const char *s){
    #ifndef ONLINE_JUDGE
    	char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
    #endif
    }
    ll rd(){ll s=0;int c,b=0;while(((c=getchar())<'0'||c>'9')&&c!='-');if(c=='-'){c=getchar();b=1;}do{s=s*10+c-'0';}while((c=getchar())>='0'&&c<='9');return b?-s:s;}
    void put(int x){if(!x){putchar('0');return;}static int c[20];int t=0;while(x){c[++t]=x%10;x/=10;}while(t)putchar(c[t--]+'0');}
    int upmin(int &a,int b){if(b<a){a=b;return 1;}return 0;}
    int upmax(int &a,int b){if(b>a){a=b;return 1;}return 0;}
    ll a[100010];
    ll s[100];
    ll sum;
    int n;
    void insert(ll v)
    {
    	for(int i=62;i>=0;i--)
    		if(!((sum>>i)&1)&&((v>>i)&1))
    		{
    			if(!s[i])
    			{
    				s[i]=v;
    				return;
    			}
    			v^=s[i];
    		}
    	for(int i=62;i>=0;i--)
    		if(((sum>>i)&1)&&((v>>i)&1))
    		{
    			if(!s[i])
    			{
    				s[i]=v;
    				return;
    			}
    			v^=s[i];
    		}
    }
    int main()
    {
    	open("loj6060");
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		a[i]=rd();
    		sum^=a[i];
    	}
    	for(int i=1;i<=n;i++)
    		insert(a[i]);
    	ll ans=0;
    	for(int i=62;i>=0;i--)
    		if(!((sum>>i)&1)&&((ans^s[i])+(sum^ans^s[i])>ans+(sum^ans)||((ans^s[i])+(sum^ans^s[i])==ans+(sum^ans)&&(ans^s[i])>ans)))
    			ans^=s[i];
    	for(int i=62;i>=0;i--)
    		if(((sum>>i)&1)&&((ans^s[i])+(sum^ans^s[i])>ans+(sum^ans)||((ans^s[i])+(sum^ans^s[i])==ans+(sum^ans)&&(ans^s[i])>ans)))
    			ans^=s[i];
    	printf("%lld
    ",sum^ans);
    	return 0;
    }
    
  • 相关阅读:
    apache配置虚拟主机及虚拟目录
    Apache的443端口被占用解决方法
    Windows下XDebug 手工配置与使用说明
    php中输入这个网站的网址跳转到你定义的页面代码
    XAMPP的使用说明
    Linux致命命令
    wget 命令用法详解
    Linux 关机命令详解
    LINUX视频教程下载地址
    ubuntu 开机自动开启数字小键盘
  • 原文地址:https://www.cnblogs.com/ywwyww/p/9209779.html
Copyright © 2011-2022 走看看