【2022noip多校】异或

【题目描述】

对于一个元素介于 [0,2m) 且互不相同的长度为 n 的序列 a1,a2...,an ,定义它的特征序列为 p0,p1,...,p2m1 ,其中 pi 表示使得 apii 的异或值最大的下标。

​ 形式化地,定义 pi=argmax1<=j<=naji

给定一个特征序列 p ,求有多少个满足要求的原序列 a 可以得到这个特征序列。

​ 答案对 109+7 取模

【样例】

【样例输入1】
6 3
1 1 2 2 3 4 5 6
【样例输出1】
4

【解析】

首先明确,合法的 p 中,必定出现完整的 [1,n]

[0,2m1) 的二进制形式依次写出(取 m=3

000 001 010 011 100 101 110 111

发现每次取一半,在第 k 次时,会使从高到底第 k 为发生 0,1 分割

所以考虑分治:

设状态 [l,r] 表示在 [l,r] 中,任意 apii 的前 dep 位相同, dep 表示分治深度。

其实这也代表了 apidep 位相同,这个可以从之前的例子中看出。

接下来考虑下一层:

  1. 若集合 pl,..,mid=pmid+1,..,r 则表示下一位这两边也相同,则将方案数乘二,问题规模减半

  2. 若集合 pl,..,mid!=pmid+1,..,r 则代表下一位不同,且可以得出 al,..,middep 位一定为 1amid+1,..,rdep 位一定为 0,因为要保持最大且左区间的 dep 位均为 0 ,右区间均为 1 所以有以上结论。之后这两种情况就独立了,乘法原理直接乘起来就可以了。

    考虑无解,即集合 pl,..,mid!=pmid+1,..,rpl,..,midpmid+1,..,r!= 就无解。

【CODE】

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn = (1<<16)+33;
inline ll read_int(){
	ll a=0;bool f=0;char g=getchar();
	while(g<'0'||'9'<g) {if(g=='-') f=1;g=getchar();}
	while('0'<=g&&g<='9') a=a*10+g-'0',g=getchar();
	return f ? -a : a;
}

inline void write(ll a,bool b=1){
	if(a<0) a=-a,putchar('-');
	ll lin[30],top=0;
	while(a) lin[++top]=a%10,a/=10;
	if(top==0) lin[++top]=0;
	while(top) putchar(lin[top--]+'0');
	if(b) putchar('\n');
}

ll n,m,mod=1e9+7;
ll sj[maxn];
ll vis[maxn];

inline ll fz(ll l,ll r){
    // cout<<l<<" "<<r<<endl;
    if(l==r) return 1;
    ll mid=(l+r)>>1;
    int bt=0,xd=0;
    set<int> a,b;
    int f=0;
    for(int i=l;i<=mid;i++) a.emplace(sj[i]);
    for(int i=mid+1;i<=r;i++) b.emplace(sj[i]),f= (f||(a.find(sj[i])!=a.end()) ? 1 : 0);
    if(f&&a!=b) return 0;
    if(a==b) return (ll)2*fz(l,mid)%mod;
    else return fz(l,mid)*fz(mid+1,r)%mod;
}

inline void read(){
    n=read_int(),m=read_int();
    for(int i=1;i<=(1<<m);i++) sj[i]=read_int(),vis[sj[i]]=1;
    for(int i=1;i<=n;i++){
        if(vis[i]==0) {write(0);return;}
    }
    write(fz(1,(1<<m)));
}

int main (){
    // freopen(".out","w",stdout);
    read();
    // while(1) getchar();
}

【后记】

如有大佬知道之前那个合法的 p 中必有 [i,n] 是如何证明的,请留言

posted @   轩Demonmaster  阅读(81)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示