题目链接:http://hihocoder.com/problemset/problem/1509
解题方案:首先,两个数谁大谁小一定是看这两个数的高位里面第一个不相同的数字,不管是10进制还是2进制都是这样判断。然后可以将所有的a[i]看成是60位的二进制数,a[i]和a[i+1]二进制串相同的地方和s异或后一定还是一样的,不同的地方和s异或后一定还是不一样的,因为(0,1)^0=(0,1),(0,1)^1=(1,0),(0,0)^0=(0,0),(1,1)^1=(0,0)。所以s的二进制串若想满足题意,对a[i]和a[i+1]高位里面第一个不相同的位置j,s[j]是固定的。故只需要将s所有固定的位置的值求出来,期间判断一下是否出现矛盾,然后就可以算出符合题意的s的个数了。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <cmath> #include <vector> #include <queue> #include <stack> #include <set> #include <map> using namespace std; #define FOR(i,k,n) for(int i=k;i<n;i++) #define FORR(i,k,n) for(int i=k;i<=n;i++) #define scan(a) scanf("%d",&a) #define scann(a,b) scanf("%d%d",&a,&b) #define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c) #define mst(a,n) memset(a,n,sizeof(a)) #define ll long long #define N 65 #define mod 1000000007 #define INF 0x3f3f3f3f const double eps=1e-8; const double pi=acos(-1.0); int a[N][N]; int s[N]; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n; while(cin>>n) { mst(a,0); mst(s,-1); FOR(i,0,n) { ll tmp; cin>>tmp; int cnt=0; while(tmp) { a[i][cnt++]=tmp&1; tmp>>=1; } } int flag=1; FOR(i,0,n-1) { if(!flag) break; for(int j=59;j>=0;j--) { if(a[i][j]!=a[i+1][j]) { if(a[i][j]==0&&a[i+1][j]==1) { if(s[j]==1) { flag=0; break; } s[j]=0; } else { if(s[j]==0) { flag=0; break; } s[j]=1; } break; } } } if(!flag) printf("0\n"); else { int cnt=0; FOR(i,0,60) if(s[i]==-1) cnt++; //printf("%d\n",cnt); cout<< ((ll)(1)<<cnt) <<endl; } } return 0; }
