题意
又又又不想说题意
题解
首先考虑 a a a和 b b b与 c c c异或,无论 c c c是什么, a x o r c a\ xor\ c a xor c和 b x o r c b\ xor\ c b xor c的差别在于 a a a和 b b b的最高不同位,而 x i x_i xi一共 m m m位。
我们考虑
{
0...
2
m
−
1
}
\{0...2^{m-1}\}
{0...2m−1},首先可以发现,前半部分最高位都是
0
0
0,后半部分都是
1
1
1,并且
i
i
i和
i
+
2
m
−
1
i+2^{m-1}
i+2m−1除了第一位都相同。
如果
x
i
x_i
xi的最高位有
1
1
1,显然前面一定会选
1
1
1的,有
0
0
0,后面一定会选
0
0
0。
所以如果 x i x_i xi最高位不完全相同,必然 x p i x_{pi} xpi的最高位已经确定,且前面和后面的 p i p_i pi没有交集,因为选择的 x p i x_{p_i} xpi前面一定是 1 1 1,后面一定是 0 0 0。
如果最高位相同的话,那就是说没得选择,并且 p i p_i pi和 p i + 2 m − 1 p_{i+2^{m-1}} pi+2m−1必然相同,因为他们除了最高位之外剩下是相同的,所以剩下的要最大且唯一必然只有一种选择,所以是相同的,如果不同就说明最高位相同的条件不成立。
总结一下就是:
如果前后没有交集,就是最高位不完全相同
如果前后有交集,但是对应位相同,显然最高位相同。
其他,就是无解
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn = 6e6+1000;
const ll mod = 1e9 + 7;
int p[maxn],m,n;
ll ans=1;
void slove(int l,int r){
// cout<<l<<" "<<r<<" "<<ans<<" "<<endl;
if(l==r){return ;}
int mid=(l+r)>>1,ok=1;
// cout<<mid<<endl;
for(int i=l,j=mid+1;i<=mid&&j<=r;i++,j++)if(p[i]!=p[j])ok=0;
if(ok){
ans=ans*2%mod;
slove(l,mid);
return ;
}
set<int>s;
for(int i=l;i<=mid;i++)s.insert(p[i]);
for(int i=mid+1;i<=r;i++){
if(s.find(p[i])!=s.end())ans=0;
}
slove(l,mid),slove(mid+1,r);
}
int main(){
cin>>m>>n;
for(int i=0;i<(1<<m);i++)scanf("%d",p+i);
slove(0,(1<<m)-1);
cout<<ans<<endl;
}