程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> CF 251D Two Sets(位操作,解方程)

CF 251D Two Sets(位操作,解方程)

編輯:C++入門知識

題目:給出n個數,分為兩個集合, 可以為空。              第一個集合,數值異或為x1,第二個集合,異或為x2              要求x1+x2最大,相同的情況下x1盡量小       首先感謝xiaodao的指導。   第一步要想到的是貪心。   因為化為兩個整數的和最大,我們將所有位先分離   如果n個數中,存在當前位的有m個。那麼也就是當前位有m個1   如果m為偶數,且m不為0,那麼肯定分為兩個奇數集合,那麼對於兩個集合,當前位都為1,肯定為最優   如果m為奇數,則只能分為奇+偶,要求x1盡量小,肯定給1號集合偶數個。   a11*x1 ^ a12*x2 ... a1n*xn = b1 a21*x1 ^ a22*x2 ... a2n*xn = b2 ... a62_1*x1 ^ a62_2*x2^ ... a62_n*xn =  b62   那麼就得到這樣對於每一位的方程,解出x1,x2……xn就行了   ai_j表示的是對於第j個數,第i位是1還是0   xi表示第i個數是否在第1個集合內。   注意:貪心要從高位到低位貪心              我的寫法是,加入一個方程,便開始異或處理,也可以將所有的方程一起再做   不明白的地方:為什麼我這樣子,必須要從偶數先貪心,否則會WA,感覺這個沒有影響啊,sad   難道是1+1比1+0要優秀???     [cpp]  #include<iostream>    #include<cstdio>    #include<map>    #include<cstring>    #include<cmath>    #include<vector>    #include<algorithm>    #include<set>    #include<string>    #include<queue>    #include<bitset>    #define inf 1<<30    #define M 2005    #define N 100000    #define maxn 300005    #define eps 1e-10    #define zero(a) fabs(a)<eps    #define Min(a,b) ((a)<(b)?(a):(b))    #define Max(a,b) ((a)>(b)?(a):(b))    #define pb(a) push_back(a)    #define mp(a,b) make_pair(a,b)    #define mem(a,b) memset(a,b,sizeof(a))    #define LL long long    #define lson step<<1    #define rson step<<1|1    #define MOD 1000000009    #define sqr(a) ((a)*(a))    #define Key_value ch[ch[root][1]][0]    #pragma comment(linker, "/STACK:1024000000,1024000000")    using namespace std;   vector<bitset<N> >a;   vector<int>b;  //equation a*x=b      LL num[N];   int n,cnt[62];   int important[62];   int ans[N]={0};   void add(bitset<N>A,int B){       int m=a.size();       for(int i=0;i<m;i++){           if(A[important[i]]){               A^=a[i];               B^=b[i];           }       }       int idx=-1;       for(int i=0;i<n;i++)           if(A[i]){               idx=i;               break;           }       if(idx==-1) return ;       important[m]=idx;       for(int i=0;i<m;i++){           if(a[i][idx]){               a[i]^=A;               b[i]^=B;           }       }       a.pb(A);b.pb(B);   }   int main(){       scanf("%d",&n);       for(int i=0;i<n;i++){           scanf("%I64d",&num[i]);           for(int j=0;j<62;j++)               cnt[j]+=(num[i]>>j)&1;       }       //even        for(int i=61;i>=0;i--){           if(cnt[i]&&!(cnt[i]&1)){               bitset<N>t;               t.reset();               for(int j=0;j<n;j++)                   t[j]=(num[j]>>i)&1;               add(t,1);           }       }       //odd        for(int i=61;i>=0;i--){            if(cnt[i]&&(cnt[i]&1)){               bitset<N>t;               t.reset();               for(int j=0;j<n;j++)                   t[j]=(num[j]>>i)&1;               add(t,0);           }       }       for(int i=0;i<a.size();i++){           ans[important[i]]=b[i];       }       for(int i=0;i<n;i++)           printf("%d%c",2-ans[i],i==n-1?'\n':' ');       return 0;   }     #include<iostream> #include<cstdio> #include<map> #include<cstring> #include<cmath> #include<vector> #include<algorithm> #include<set> #include<string> #include<queue> #include<bitset> #define inf 1<<30 #define M 2005 #define N 100000 #define maxn 300005 #define eps 1e-10 #define zero(a) fabs(a)<eps #define Min(a,b) ((a)<(b)?(a):(b)) #define Max(a,b) ((a)>(b)?(a):(b)) #define pb(a) push_back(a) #define mp(a,b) make_pair(a,b) #define mem(a,b) memset(a,b,sizeof(a)) #define LL long long #define lson step<<1 #define rson step<<1|1 #define MOD 1000000009 #define sqr(a) ((a)*(a)) #define Key_value ch[ch[root][1]][0] #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; vector<bitset<N> >a; vector<int>b;  //equation a*x=b   LL num[N]; int n,cnt[62]; int important[62]; int ans[N]={0}; void add(bitset<N>A,int B){     int m=a.size();     for(int i=0;i<m;i++){         if(A[important[i]]){             A^=a[i];             B^=b[i];         }     }     int idx=-1;     for(int i=0;i<n;i++)         if(A[i]){             idx=i;             break;         }     if(idx==-1) return ;     important[m]=idx;     for(int i=0;i<m;i++){         if(a[i][idx]){             a[i]^=A;             b[i]^=B;         }     }     a.pb(A);b.pb(B); } int main(){     scanf("%d",&n);     for(int i=0;i<n;i++){         scanf("%I64d",&num[i]);         for(int j=0;j<62;j++)             cnt[j]+=(num[i]>>j)&1;     }     //even     for(int i=61;i>=0;i--){         if(cnt[i]&&!(cnt[i]&1)){             bitset<N>t;             t.reset();             for(int j=0;j<n;j++)                 t[j]=(num[j]>>i)&1;             add(t,1);         }     }     //odd     for(int i=61;i>=0;i--){          if(cnt[i]&&(cnt[i]&1)){             bitset<N>t;             t.reset();             for(int j=0;j<n;j++)                 t[j]=(num[j]>>i)&1;             add(t,0);         }     }     for(int i=0;i<a.size();i++){         ans[important[i]]=b[i];     }     for(int i=0;i<n;i++)         printf("%d%c",2-ans[i],i==n-1?'\n':' ');     return 0; }  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved